Redis位图的使用

Redis位图的使用

June 16, 2024
后端开发, Redis
Redis

位图的概念及原理 #

我们可以把位图理解成一个bit数组,每个元素的值是0或1。

下面用一张简单的图来解释一下: redis-map

我们可以用第一位来存储用户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。