Redis中Bitmap基本操作与面试常问场景

Bitmap是什么?

Redis中的Bitmap并不是一种单独的数据结构类型,而是在String这种数据结构中的一种面向位的一系列操作。

Bitmap相关的API介绍与使用演示


SETBIT、GETBIT

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这段命令,最终对应二进制:01000001,在ASCII中就表示为“A”。


BITCOUNT

查看二进制位上1的个数,注意统计的粒度为一个byte,下标指的是每个byte的下标,统计一个byte中1的个数。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


BITOP

在这里插入图片描述
这个命令相对复杂一些,主要作用是在多个键(包含字符串值)之间执行按位运算,并将结果存储在目标键中。

该BITOP命令支持四个位运算:AND,OR,XOR 和NOT

在这里插入图片描述
简单说明一下,上面这段命令相当于让0100 0001和0100 0010做与运算,最终得到0100 0000,对应ASCII表示为“@”。

也可以或运算,得到的结果就是0100 0011,表示为“C”。

在这里插入图片描述


使用场景

基于上面这几个API,你现在已经可以用来干一些事情,比如用来统计用户不定周期的活跃情况,统计用户的在线状态等等类似的可以用0/1两种状态来完成业务逻辑的都可以,并且由于是基于bit的操作,非常的节省内存空间。

面试常问

1、在随机的周期内统计每个用户的登录天数

假设你的系统现在有1000W的用户,并且需要在最近1年的时间范围内实现随机的时间窗口,统计每个用户登录系统的天数。

  • 传统的实现方式:使用数据库来存储每个用户每一天的登录情况,当天登录就生成一条记录,或者每天都生成一条记录然后通过一个字段用来标识是否登录。

1000W的用户假如每天都登录,一共要滚动记录365天,所以最终数据库中的数据量就是1000W*365 = 36.5亿条数据,
一条数据算少一点,就按10个字节来算,那么总共大概还需要34G的存储容量。

如果要实现1年范围内各种时间窗口的统计,还需要消耗极大的检索时间。

  • Bitmap的实现方式:使用二进制上的每一位来表示每一天,0:表示未登陆,1:表示登陆,也就是一个用户需要365个bit,取个整就是46个字节,那么1000W个用户就是:1000W*46byte ≈ 440M。

并且统计时,也只需要简单的一个bitcount命令即可满足1年范围内各种时间窗口的统计。

两者无论从检索性能上还是存储容量上相比之间的差距立竿见影。

在这里插入图片描述

这段命令表示,zs这个用户,分别在第1、2、3、15天登陆了系统,并且通过bitcount zs 0 0,统计出最近8天内登陆了3次,通过bitcount zs 0 1,统计出最近16天内登陆了4次。

当然如果要统计最近7天内的登录情况,就需要读出来并转成二进制,单独判断二进制位上前7位为1的数量即可。

2、活跃用户统计

还是1000W的用户,假设规定最近3天内登陆过的就为活跃用户,如何统计?

按照上面的思路,现在只需要转换一下方向,把日期作为key,把用户ID作为offset即可。

在这里插入图片描述

这段命令表示,先假设20200101用户id下标1,2,3登录了,2020012用户id下标1登录了,20200103用户id下标4登录了,然后要统计最近3天,就用20200101、20200102、20200103做或运算,最终得到x,对应的二进制就是1111000,也就是前4个下标为1,那么就表示id为1,2,3,4的用户最近3天登录了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值