1 记录在线用户数(活跃用户)?
比如redis中键a的value数据的二进制码是
0110 0110 0001
它总共有12位,在redis的位操作中,二进制中的第几位称为offset。
我们可以这样将这个数据的第10位设置为1:
setbit a 10 1
这样,原来的数据就变成了
0110 0110 0101
如果key不存在,也会自动创建。
当然,如果某个位还不存在,redis也会自动填充。
可以通过getbit获取某个二进制位的值
getbit a 10 //获取键a的值上第10位的值(0或1两种状态)
这是所谓的位图。
那么我们考虑在redis中放一个key,通过这个key直接操作二进制位,redis中单个key的最大值是512M,可以达到40多亿bit,足够很多业务的需要了。我们以用户id作为offset,该offset的值作为是否活跃的值即可达到我们的目的。这样只需要一个key就能解决对所有数据的查询问题。假设我们的id最大值是1亿,那么我们需要一亿个bit就行了,相当于只需要1亿/(810241024)=11.9M内存。这里大家了解下二进制就能理解。
//用户id123456是活跃用户
setbit a 123456 1
//用户id234567不是活跃用户
setbit a 234567 0
--------实际场景---------
如果需要统计每天用户访问量,以日期为key,用户id为offset,访问了以后设置为1 。
如:setbit 20190506 123456 1 这条命令算作一个用户访问后加1;
使用BITCOUNT 20190506命令来获得key为20190506时一共有多少个offset被设置为1;
优点:占用内存更小,查询方便,可以指定查询某个用户,数据可能略有瑕疵,对于非登陆的用户,可能不同的key映射到同一个id,否则需要维护一个非登陆用户的映射,有额外的开销。
缺点:如果用户非常的稀疏,那么占用的内存可能比方法一更大。