前言
不知你大规模地用过redis吗?还是仅仅作为缓存的工具?在Redis中使用最多的就是集合了,举个例子,如下场景:
- 签到系统中,一天对应一系列的用户签到记录 。
- 电商系统中,一个商品对应一系列的评论 。
- 交友系统中,某个用户的一系列的好友 。
- 交友系统中,需要统计每天的新增好友,以及双方的共同好友 。
- 电商系统中,需要统计评论列表中的最新评论 。
- 签到系统中,需要统计连续一个月的签到的用户数量 。
只有针对不同场景,选择合适的集合,统计才能更方便 。
一、聚合统计
聚合统计指的是多个元素聚合的结果,比如统计多个集合的交集、并集、差集 。
在你需要对多个集合做聚合统计的时候,Set集合是个不错的选择,除了其中无重复的数据外,Redis还提供了对应的API 。
【一个亿的keys,Redis如何统计?】1.交集
在上述的例子中交友系统中统计双方的共同好友正是聚合统计中的交集 。
在Redis中可以userid作为key,好友的userid作为value,如下图:
![一个亿的keys,Redis如何统计?](http://img.jiangsulong.com/230818/1R3064V5-0.png)
文章插图
统计两个用户的共同好友只需要两个Set集合的交集,命令如下;
SINTERSTORE userid:new userid:20002 userid:20003
上述命令运行完成后,userid:new这个key中存储的将是userid:20002、userid:20003两个集合的交集 。
2.差集
举个例子:假设交友系统中需要统计每日新增的好友,此时就需要对临近两天的好友集合取差集了,比如2020/11/1日的好友是set1,2020/11/2日的好友是set2,此时只需要对set1和set2做差集 。
此时的结构应该如何设计呢?如下图:
![一个亿的keys,Redis如何统计?](http://img.jiangsulong.com/230818/1R30B455-1.png)
文章插图
userid:20201101这个key记录了userid用户的2020/11/1日的好友集合 。
差集很简单,只需要执行SDIFFSTORE命令,如下:
SDIFFSTORE user:new userid:20201102 userid:20201101
执行完毕,此时的user:new这集合将是2020/11/2日新增的好友 。
这里还有一个更贴切的例子,微博上有个可能认识的人功能,可以使用差集,即是你朋友的好友减去你们共同的好友即是可能认识的人 。
3.并集
还是差集的那个例子,假设需要统计2020/11/01和2020/11/2总共新增的好友,此时只需要对这两日新增好友的集合做一个并集 。命令如下:
SUNIONSTORE userid:new userid:20201102 userid:20201101
此时新的集合userid:new则是两日新增的好友 。
4.总结
Set集合的交差并的计算复杂度很高,如果数据量很大的情况下,可能会造成Redis的阻塞 。
那么如何规避阻塞呢?建议如下:
- 在Redis集群中选一个从库专门负责聚合统计,这样就不会阻塞主库和其他的从库了
- 将数据交给客户端,由客户端进行聚合统计 。
在一些电商网站中可以看到商品的评论总是最新的在上面,这个是怎么做的呢?
最新评论列表包含了所有的评论,这就要集合对元素进行保序存储了 。也就是说集合中的元素必须按序存储,称之为有序集合 。
Redis中的四种集合中List和Sorted Set属于有序集合 。
但是List和Sorted Set有何区别呢?到底使用哪一种呢?
List是按照元素进入顺序进行排序,而Sorted Set可以根据元素权重来排序 。
比如可以根据元素插入集合的时间确定权值,先插入的元素权重小,后插入的元素权重大 。
针对这一例子中,显然这两种都是能够满足要求的,List中分页查询命令LRANGE和Sorted Set分页查询命令ZRANGEBYSCORE 。
但是就灵活性来说,List肯定不适合,List只能根据先后插入的顺序排序,但是大多数的场景中可能并不只是按照时间先后排序,可能还会按照一些特定的条件,此时Sorted Set就很合适了,只需要根据独有的算法生成相应的权重即可 。
三、二值状态统计
二值状态指的是取值0或者1两种;在签到打卡的场景中,只需要记录签到(1)和未签到(0)两种状态,这就是典型的二值状态统计 。
二值状态的统计可以使用Redis的扩展数据类型Bitmap,底层使用String类型实现,可以把它看成是一个bit数组 。关于详细内容后续介绍.........
推荐阅读
- 百度判断文章是否原创的方法如下
- 首个Unified Redis Release,Redis影响最深远的版本发布
- Redis的原理,及各个组件和操作。
- 人工智能搜索大战中 必应丝毫未能撬动谷歌的地位
- k8s 用户角色 权限的划分
- Oracle数据库的一些常见操作命令示例
- Springboot2 什么才是真正的架构设计?
- DBA致命的低级工作?超大型系统数据库版本质量控制
- 如何调用AI室内设计软件的API接口
- 字节跳动的多云云原生实践之路