Redis 应用场景

2022-09-27 08:21:30 浏览数 (1)

首先,总结一下这些应用场景,它们不是独立存在的,很多都还是要依赖mysql;甚至项目初期这些都不是第一选择,很多场景mysql也能做,并且更简单

生成唯一的随机数

很多网站的详情页链接都有一个随机数,比如http://www.cuiwei.net/p/1937090613https://www.zhihu.com/question/48759965https://segmentfault.com/a/1190000041091095

通常的做法是:一个code(id,article_id,code,used_time)表,一个article(id,code, ...)表,在添加文章时从code表选一个未使用的跟这篇文章绑定就可以了,前提是code表要有足够的码

下面重点来了,如何生成唯一的随机数?方法有很多,这里直接介绍使用 Redis 集合

如下,第一批可以直接用,第二批及以后的批次需要和之前的批次求差集,确保我有的你没有才能往数据库里写

代码语言:javascript复制
    function generateCode($length=5000){
        $codes=[];
        for($i=0; $i<$length; $i  ){
            $codes[]=mt_rand(1000000000, 1999999999);
        }
        return $codes;
    }

        $ok = $this->cache()->sAddArray('code', $this->generateCode());//第一批
        $ok2 = $this->cache()->sAddArray('code2', $this->generateCode());//第二批

        $sInter=$this->cache()->sInter('code2', 'code');//交集,我们都有的
        $sDiff=$this->cache()->sDiffStore('code3', 'code2', 'code');//差集,我有的你没有,并将结果保存到code3

        $count=$this->cache()->sCard('code');
        $list=$this->cache()->sMembers('code');
        $count2=$this->cache()->sCard('code2');
        $list2=$this->cache()->sMembers('code2');
        $this->status(0, ['ok'=>$ok, 'ok2'=>$ok2, 'count'=>$count, 'count2'=>$count2, 'sInter'=>$sInter, 'sDiff'=>$sDiff, 'list'=>$list, 'list2'=>$list2]);

抽奖

代码语言:javascript复制
        $ok = $this->cache()->sAddArray('users', [1,2,3,4,5,6,7,8,9]);
        $users=$this->cache()->sPop('users', 2);//随机选出2名幸运观众,选中后不在参与下面的抽奖
//        $users=$this->cache()->sRandMember('users', 2);//随机选出2名幸运观众,选中后还可以继续参与下面的抽奖
        $this->status(0, ['ok'=>$ok, 'users'=>$users]);

浏览量排行榜

代码语言:javascript复制
        $ok = $this->cache()->zIncrBy('hotblog', 1, 100);//id为100的文章每次访问加1
        $list=$this->cache()->zRevRangeByScore('hotblog', 30, 10, ['withscores' => TRUE, 'limit' => [0, 10]]);//浏览量在10~30之间的
        $list=$this->cache()->zRevRange('hotblog', 0, 2, true);//浏览量前3的文章
        $list=$this->cache()->zRange('hotblog', 0, 2, true);//浏览量垫底的3篇文章
        $rank=$this->cache()->zRevRank('hotblog', 100) 1;//id为100的文章排第几

互相关注,可能认识

代码语言:javascript复制
        $this->cache()->sAdd('user_1_fans', 2,3,4,5,6);//user1的粉丝
        $this->cache()->sAdd('user_1_follow', 2,4);//user1的关注
        $this->cache()->sAdd('user_2_fans', 1);//user2的粉丝
        $this->cache()->sAdd('user_2_follow', 1,3);//user2的关注
        //互相关注(看我的关注列表,哪些是互相关注?
        $sInter=$this->cache()->sInter('user_1_fans', 'user_1_follow');
        //可能认识(user1可能认识/喜欢的人?如user1关注了user2,那么user2的关注列表可能是user1喜欢的
        $sDiff=$this->cache()->sDiff('user_2_follow', 'user_1_follow');

点赞

代码语言:javascript复制
        $this->cache()->sAdd('article_100_like', 1);//user1给article100点赞
        $this->cache()->sRem('article_100_like', 1);//user1取消点赞
        $this->cache()->sIsMember('article_100_like', 1);//user1是否点赞
        $this->cache()->sMembers('article_100_like');//点赞的所以用户
        $this->cache()->sCard('article_100_like');//点赞总数

附近的人

代码语言:javascript复制
        $r=$this->cache()->geoadd('users', 114.09981,33.585519, 'user1');
        $r=$this->cache()->geoadd('users', 114.070524,33.59067, 'user2');
        $r=$this->cache()->geoadd('users', 113.971066,33.577242, 'user3');

        //两个成员之间的距离
        $r=$this->cache()->geodist('users', 'user1', 'user2', 'km');
        //获取方圆500m的用户
        $r=$this->cache()->geoRadiusByMember('users', 'user1', 500, 'm');

队列

一些耗时的任务,可以加到队列里异步处理。如果想用redis写一个完善的队列是很复杂的,建议使用 beanstalkd、rabbitmq等

代码语言:javascript复制
        $r=$this->cache()->lPush('list', 2);//左边进
        $r=$this->cache()->rPop('list');//右边出

token登陆令牌

这是我最常用的一个场景,当初从 memcache 切换到 redis 就是因为这个

用户登陆成功会给他设置一个token,并返回给前端;前端每次请求接口会把token带过来,后台验证这个token是否存在,不存在则提示用户重新登陆

代码语言:javascript复制
        $r=$this->cache()->set('user_1_token', 'aaa', 7*24*3600);//写入token,并设置7天后过期
        $r=$this->cache()->get('user_1_token');//取出

限流

详见 http://www.cuiwei.net/p/1203489253

参考

https://blog.csdn.net/agonie201218/article/details/123640871

https://blog.csdn.net/weixin_40205234/article/details/124614720

0 人点赞