![](https://uploadfiles.nowcoder.com/images/20220122/534718694_1642831512375_5A9F6A51E994577B680762E995D412F0) 1️⃣业务场景分析 关注微博 登录首页展示了我关注的所有人发的微博,展示形式是列表 滚动有分页加载 ![](https://uploadfiles.nowcoder.com/images/20220122/534718694_1642831512715_5A9F6A51E994577B680762E995D412F0) 2.个人微博 我发的微博展示在个人微博,展示形式也是列表 滚动有分页加载 ![](https://uploadfiles.nowcoder.com/images/20220122/534718694_1642831513114_5A9F6A51E994577B680762E995D412F0) 2️⃣ 基于redis技术方案 发微博 文章 个人微博 关注微博 用户 服务器 采用map结构保存 采用list结构保存文章id 也采用list结构保存文章id 关注微博和个人微博的展示形式都是列表,用redis的list结构存储。 滚动有分页加载,用redis的 lrange key start stop命令范围查询元素。 问题: 每个人都有2个list:一个是个人list,一个是关注list,而这2个list每次发微博都会push到个人list和关注list,这2个list存在性能的问题,就是这个list无线增长。时间久了redis数据持续膨胀。 最有效的解决方法是限制次数,常见的场景是 qq群,微信群限定人数 百度搜索限定了搜索出来75页 限定个人微博和关注微博的长度为1000,即,发微博的时候,往个人list和关注list push完成后,把list的长度剪切为1000,具体的技术方案采用list 的ltrim命令来实现。 ltrim key start end截取队列指定区间的元素,其余元素都删除 ![](https://uploadfiles.nowcoder.com/images/20220122/534718694_1642831513780_5A9F6A51E994577B680762E995D412F0) 3️⃣代码编写 ✏️ 发微博,写入个人主页 /**
* push到个人主页
*/
public void pushHomeList(Integer userId,Integer postId){
//个人微博列表key
String key="myPostBox:list:"+userId;
//把该微博文章id推送到队列
this.redisTemplate.opsForList().leftPush(key,postId);
//限定长度,防止膨胀,截取前1000条
if(this.redisTemplate.opsForList().size(key)>1000){
this.redisTemplate.opsForList().trim(key,0,1000);
}
}
复制代码 ✏️ 发微博,批量推送给粉丝 /**
* 发一条微博,批量推送给所有粉丝
*/
private void pushFollower(int userId,int postId){
SetOperations opsForSet = redisTemplate.opsForSet();
//读取粉丝集合,粉丝集合用set保存
String followerkey=Constants.CACHE_KEY_FOLLOWER+userId;
//千万不能取set集合的所有数据,如果数据量大的话,会卡死
// Set sets= opsForSembers(followerkey);
Cursor cursor = opsForSet.scan(followerkey, ScanOptions.NONE);
try{
while (cursor.hasNext()){
//拿出粉丝的userid
Integer object = cursor.next();
//该粉丝的关注列表key
String key= "myAttentionBox:list:"+object;
//把该文章添加到队列
this.redisTemplate.opsForList().leftPush(key,postId);
}
}catch (Exception ex){
log.error("",ex);
}finally {
try {
cursor.close();
} catch (IOException e) {
log.error("",e);
}
}
}
复制代码 ✏️ 查看个人列表 /**
* 获取个人主页列表
*/
public PageResult homeList(Integer userId,int page, int size){
//分页
PageResult pageResult=new PageResult();
List list=null;
long start = (page - 1) * size;
long end = start + size - 1;
try {
String key= "myPostBox:list:"+userId;
//1.查询用户的总数
int total=this.redisTemplate.opsForList().size(key).intValue();
//设置总数
pageResult.setTotal(total);
//2.采用redis list数据结构的lrange命令实现分页查询。
list = this.redisTemplate.opsForList().range(key, start, end);
//3.根据文章id去redis查询明细,redis没有就去db拿
List contents=this.getContents(list);
pageResult.setRows(contents);
}catch (Exception e){
log.error("异常",e);
}
return pageResult;
}
复制代码 ✏️ 查看关注列表 /**
* 获取关注列表
*/
public PageResult attentionList(Integer userId,int page, int size){
PageResult pageResult=new PageResult();
List list=null;
long start = (page - 1) * size;
long end = start + size - 1;
try {
String key= "myAttentionBox:list:"+userId;
//1.设置总数
int total=this.redisTemplate.opsForList().size(key).intValue();
pageResult.setTotal(total);
//2.采用redis,list数据结构的lrange命令实现分页查询。
list = this.redisTemplate.opsForList().range(key, start, end);
//3.根据文章id去redis查询明细,redis没有就去db拿
List contents=this.getContents(list);
pageResult.setRows(contents);
}catch (Exception e){
log.error("异常",e);
}
return pageResult;
}
复制代码 ⛳redis分布式缓存系列文章 上一章节: redis分布式缓存(三十)一一 🚀二级缓存的高并发文章PV解决方案 👍🏻:有收获的,点赞鼓励! ❤️:收藏文章,方便回看! 💬:评论交流,互相进步!
|