1

上一篇: redis学习笔记之-(1)-bitmap用法之1-统计所有用户1年的登录天数


2. bitmap使用2:上亿个用户的1周内连续活跃用户数

2.1 思路

需求2: 上亿个用户,统计一周内连续活跃用户

100000000/8/1024/1024 = 11.9M 一个bitmap占用 不到12M

好在一周只有7天, 我们用7个key的bitmap来存储状态即可,

加上最后的一个结果res的bitmap: 12*8=100M 内存即可!

遵循下面步骤即可:

  1. 用户编号是前提, 每个用户的编号从1到n(n=就是说的那个上亿的最大值);
  2. 声明7个bitmap, 从周一到周日: mon tue wed thur fri sat sun;
  3. 每个用户编号所在的offset在周1如果登录了, 就是1, 没登录就是0;
  4. 7个bitmap都设值记录;
  5. bitop 对7个bitmap进行位AND操作, 7天都登录的当天的位上才是1
  6. 最后的结果进行bitcount操作, 就是上亿用户一周内连续活动的人数!
  7. 如果想知道连续活跃的用户都有哪些人, 遍历 getbit 每一天的key(mon/tue/...) id即可!

示例: 我们模拟5个用户吧:

用户IDmontuewedthurfrisatsun
0011111111
0020000011
0031111111
0041111111
0050101011

2.2 前4步: 初始化7个bitmap

周一的key: mon, 周一所有用户的登录状态记录:

127.0.0.1:6379> setbit mon 1 1
(integer) 0
127.0.0.1:6379> setbit mon 2 0
(integer) 0
127.0.0.1:6379> setbit mon 3 1
(integer) 0
127.0.0.1:6379> setbit mon 4 1
(integer) 0
127.0.0.1:6379> setbit mon 5 0
(integer) 0

周二的key: tue, 所有用户的登录状态记录:

127.0.0.1:6379> setbit tue 1 1
(integer) 0
127.0.0.1:6379> setbit tue 2 0
(integer) 0
127.0.0.1:6379> setbit tue 3 1
(integer) 0
127.0.0.1:6379> setbit tue 4 1
(integer) 0
127.0.0.1:6379> setbit tue 5 1
(integer) 0

周三的key: wed, 所有用户的登录状态记录:

127.0.0.1:6379> setbit wed 1 1
(integer) 0
127.0.0.1:6379> setbit wed 2 0
(integer) 0
127.0.0.1:6379> setbit wed 3 1
(integer) 0
127.0.0.1:6379> setbit wed 4 1
(integer) 0
127.0.0.1:6379> setbit wed 5 0
(integer) 0

周四的key: thur, 所有用户的登录状态记录:

127.0.0.1:6379> setbit thur 1 1
(integer) 0
127.0.0.1:6379> setbit thur 2 0
(integer) 0
127.0.0.1:6379> setbit thur 3 1
(integer) 0
127.0.0.1:6379> setbit thur 4 1
(integer) 0
127.0.0.1:6379> setbit thur 5 1
(integer) 0

周五的key: fri, 所有用户的登录状态记录:

127.0.0.1:6379> setbit fri 1 1
(integer) 0
127.0.0.1:6379> setbit fri 2 0
(integer) 0
127.0.0.1:6379> setbit fri 3 1
(integer) 0
127.0.0.1:6379> setbit fri 4 1
(integer) 0
127.0.0.1:6379> setbit fri 5 0
(integer) 0

周六的key: sat, 所有用户的登录状态记录:

127.0.0.1:6379> setbit sat 1 1
(integer) 0
127.0.0.1:6379> setbit sat 2 1
(integer) 0
127.0.0.1:6379> setbit sat 3 1
(integer) 0
127.0.0.1:6379> setbit sat 4 1
(integer) 0
127.0.0.1:6379> setbit sat 5 1
(integer) 0

周日的key: sun, 所有用户的登录状态记录:

127.0.0.1:6379> setbit sun 1 1
(integer) 0
127.0.0.1:6379> setbit sun 2 1
(integer) 0
127.0.0.1:6379> setbit sun 3 1
(integer) 0
127.0.0.1:6379> setbit sun 4 1
(integer) 0
127.0.0.1:6379> setbit sun 5 1
(integer) 0

我去, 数据终于录入完了, 费劲那个~~

2.3 用bitop对7个bitmap进行位AND操作

127.0.0.1:6379> bitop and res mon tue wed thur fri sat sun
(integer) 1

2.4 bitcount对结果bitmap, 见证奇迹的时刻到了

127.0.0.1:6379> bitcount res
(integer) 3

2.5 想知道连续活跃的用户都有哪些人

getbit res 1 表示 用户编号为1的结果: 1说明用户ID=1的, 7天都活跃!

5个用户结果如下:

127.0.0.1:6379> getbit res 1
(integer) 1
127.0.0.1:6379> getbit res 2
(integer) 0
127.0.0.1:6379> getbit res 3
(integer) 1
127.0.0.1:6379> getbit res 4
(integer) 1
127.0.0.1:6379> getbit res 5
(integer) 0

2.6 扩展:

如果需求是: 求一周内活跃过的用户数: 只要将 上面命令中bitop and 改为: bitop or 即可~

连续 的话要求是AND, 活跃过 的话, 只要有一天就可以

over!

2.7 小结

bitmap的操作命令:

  • setbit key offset value
  • getbit key offset
  • bitcount key [start end]
  • bitop operation destkey [key ...]

    operation: 支持 AND/OR/NOT/XOR四种操作,除NOT 外,其他操作都可接受一个或多个 key 作输入

    destkey: 后面所有 key([key...])的与或非异或操作的结果存入一个目标key, 取个名字!

    key... 可以n个key做 与或非异或操作, 传入这些bitmap的key 列表


丰木
322 声望19 粉丝

遇见超乎想象的自己!