一文弄懂redis分布式缓存之微博推送技术方案

1️⃣业务场景分析

  1. 关注微博
  • 登录首页展示了我关注的所有人发的微博,展示形式是列表
  • 滚动有分页加载

2.个人微博

  • 我发的微博展示在个人微博,展示形式也是列表
  • 滚动有分页加载

2️⃣ 基于redis技术方案

发微博

文章

个人微博

关注微博

用户

服务器

采用map结构保存

采用list结构保存文章id

也采用list结构保存文章id

  1. 关注微博和个人微博的展示形式都是列表,用redis的list结构存储。
  2. 滚动有分页加载,用redis的 lrange key start stop命令范围查询元素。

问题: 每个人都有2个list:一个是个人list,一个是关注list,而这2个list每次发微博都会push到个人list和关注list,这2个list存在性能的问题,就是这个list无线增长。时间久了redis数据持续膨胀。

最有效的解决方法是限制次数,常见的场景是

  • qq群,微信群限定人数
  • 百度搜索限定了搜索出来75页
  1. 限定个人微博和关注微博的长度为1000,即,发微博的时候,往个人list和关注list push完成后,把list的长度剪切为1000,具体的技术方案采用list 的ltrim命令来实现。
  • ltrim key start end截取队列指定区间的元素,其余元素都删除

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<String, Integer> opsForSet = redisTemplate.opsForSet();
        //读取粉丝集合,粉丝集合用set保存
        String followerkey=Constants.CACHE_KEY_FOLLOWER+userId;
        //千万不能取set集合的所有数据,如果数据量大的话,会卡死
        // Set<Integer> sets= opsForSet.members(followerkey);
        Cursor<Integer> 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<Content> homeList(Integer userId,int page, int size){
        //分页
        PageResult<Content> pageResult=new PageResult();
        List<Integer> 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<Content> contents=this.getContents(list);
            pageResult.setRows(contents);
        }catch (Exception e){
            log.error("异常",e);
        }
        return pageResult;
    }
复制代码

✏️ 查看关注列表

    /**
     * 获取关注列表
     */
    public PageResult<Content> attentionList(Integer userId,int page, int size){
        PageResult<Content> pageResult=new PageResult();

        List<Integer> 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<Content> contents=this.getContents(list);
            pageResult.setRows(contents);
        }catch (Exception e){
            log.error("异常",e);
        }
        return pageResult;
    }
复制代码

⛳redis分布式缓存系列文章

上一章节: redis分布式缓存(三十)一一 🚀二级缓存的高并发文章PV解决方案

  • 👍🏻:有收获的,点赞鼓励!
  • ❤️:收藏文章,方便回看!
  • 💬:评论交流,互相进步!
全部评论

相关推荐

就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
05-14 20:34
门头沟学院 Java
窝补药贝八股:管他们,乱说,反正又不去,直接说680
点赞 评论 收藏
分享
06-28 22:48
已编辑
广东金融学院 Java
小浪_Coding:学院本+这俩项目不是buff叠满了嘛
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务