基于Redis的Redisson分布式列表(List)结构的RList
Java对象实现了java.util.List
接口。简直太方便了。遥想当初为了用Redis的List类型,得做如下的代码 StringRedisTemplate.opsForList()得到操作List集合的对象;
Redisson的RList相当于一个Redis的List类型的数据结构。因为其的底层实现就是Redis的List,所以其核心使用心法就是用于存储一对多的热点数据。
从我自己的公司角度的业务上来看。可以使用Redis的List来做例如 "班级-学生"、"学院-专业"、"年级-学院"等一对多的业务场景。因此,对于Redis的List这种数据结构而言,只要牢牢记住,当出现一对多的场景时,可以考虑使用List这种Redis数据结构来做热点数据的缓存。
技术参考文档:
RList<SomeObject> list = redisson.getList("anyList");
list.add(new SomeObject());
list.get(0);
list.remove(new SomeObject());
现在的需求是记录用户的操作日志。数据库里存放两个字段,一个是用户账号,一个是操作时间。
package com.tyzhou.redisson.service;
import com.tyzhou.Constant;
import com.tyzhou.redisson.mapper.LogMapper;
import com.tyzhou.redisson.model.LogDO;
import com.tyzhou.utils.CollectionUtils;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Redisson List 作为访问记录日志缓存
*
* @author zhoutianyu
* @date 2020/3/19
* @time 19:19
*/
@Service
public class LogService {
@Autowired
private LogMapper logMapper;
@Autowired
private RedissonClient redisson;
public void insertLog(String userAccount) {
LogDO log = new LogDO(userAccount);
//插入日志到数据库
logMapper.insertLog(log);
if (log.getId() > 0) {
//同时从Redis获取日志缓存,将本次日志加入进去
RList<LogDO> logList = redisson.getList(Constant.REDISSON_LOG);
logList.add(log);
}
}
//通过账号查询这个人的操作记录缓存
public List<LogDO> getLogCache(String userAccount) {
//从Redis缓存中取数据
RList<LogDO> logList = redisson.getList(Constant.REDISSON_LOG);
if (CollectionUtils.isNotEmpty(logList)) {
return logList;
}
//如果缓存中没有数据,则从数据库的日志表中查询操作日志
return logMapper.selectAll(userAccount);
}
}
package com.tyzhou.redisson.model;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class LogDO {
private Integer id;
private String userAccount;
private Date operationTime;
public LogDO(String userAccount) {
this.userAccount = userAccount;
this.operationTime = new Date();
}
}
为了保证日志与数据库中一致,所以还要添加一个定时任务,定时将日志记录加入到缓存。
package com.tyzhou.redisson.schedule;
import com.tyzhou.Constant;
import com.tyzhou.redisson.mapper.LogMapper;
import com.tyzhou.redisson.model.LogDO;
import com.tyzhou.utils.CollectionUtils;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@EnableScheduling
@EnableAsync
public class LogSchedule {
private static final Logger LOGGER = LoggerFactory.getLogger(LogSchedule.class);
@Autowired
private LogMapper logMapper;
@Autowired
private RedissonClient redisClient;
//10分钟同步一次(开发测试可增加频率)
@Scheduled(cron = "* */10 * * * ?")
@Async
public void selectLogCache() {
LOGGER.info("同步日志缓存");
RList<LogDO> logCacheList = redisClient.getList(Constant.REDISSON_LOG);
//清空所有
logCacheList.delete();
List<LogDO> logList = logMapper.selectAll("");
if(CollectionUtils.isNotEmpty(logList)){
logCacheList.addAll(logList);
}
}
}
发送几次请求,参数是某个学生。在数据库里会记录这个学生的操作日志,并将缓存日志Redisson的某个List中。
再发送查询日志的请求,先从Redisson的某个List中拿数据。如果没拿到数据,才查询一次数据库。
为了保证数据库与缓存一致,有定时任务按照一定的频率,把DB中的操作日志全部查询出来,放入Redisson的某个List中。因此下次查询的时候就可以先走缓存,而不是查询DB,从而达到为DB减少负载的目的。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://zhoutianyu.blog.csdn.net/article/details/104992226
内容来源于网络,如有侵权,请联系作者删除!