Redis位图的使用
June 16, 2024
位图的概念及原理 #
我们可以把位图理解成一个bit数组,每个元素的值是0或1。
下面用一张简单的图来解释一下:

我们可以用第一位来存储用户id为1的用户的在线状态,用第二位来存储用户id为2的用户的在线状态,以此类推。
请注意:位图是一种数据结构,不是redis独有。比如,你把Go的切片当成位数来使用,理论上也是可以实现的。
位图的优势 #
- 结构简单。
- 节约内存.
Redis位图的使用 #
常用命令 #
- setbit 更新 如下,用户1001签到:
localhost:6379> setbit list:20240616 1001 1
(integer) 0
- getbit 读取 如下,查询用户1001是否签到:
localhost:6379> getbit list:20240616 1001
(integer) 1
- bitcount 统计数量 查询某天签到的数量:
localhost:6379> bitcount list:20240616
(integer) 2
更多命令,可以查看Redis官方文档-位图
使用场景 #
Redis位图最常用的使用场景,就是用来统计状态或是否进行了某个操作,比如在线状态、签到情况统计,或者类似的功能。
经验分享-Redis位图引起的事故 #
事故描述 #
最近公司上了一个新服务,独立的集群,独立的redis,测试阶段正常,发布到生产环境,redis服务直接oom掉。服务刚上线,根本就没有几个用户,怎么可能内存用光呢?真是奇哉怪也!
事故分析 #
分析了一下大key,发现都是记录在线状态的。原来,项目上线的时候,将用户id的初始值设置的很大,导致位图占用内存空间超大。 之所以开发/测试环境没有发现这个问题,是因为开发/测试的redis实例容量比较大,而生产环境用的云redis实例容量较小(主要是贵)。
事故处理 #
升级redis服务。这也是最快最简单的解决方案(通常花钱能解决的方案,都是最快的解决方案)。 当然,我们这种场景,其实还有一种方案,就是读写redis位图的时候,将用户减去初始值,比如id是5000000001,写的时候就用1。