上一篇: 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 到 n(n= 就是说的那个上亿的最大值);
- 申明 7 个 bitmap, 从周一到周日: mon tue wed thur fri sat sun;
- 每个用户编号所在的 offset 在周 1 如果登录了, 就是 1, 没登录就是 0;
- 7 个 bitmap 都设值记录;
- 用 bitop 对 7 个 bitmap 进行位AND 操作, 7 天都登录的当天的位上才是 1
- 最初的后果进行
bitcount
操作, 就是上亿用户一周内间断
流动的人数! - 如果想晓得间断沉闷的用户都有哪些人, 遍历
getbit 每一天的 key(mon/tue/...) id
即可!
示例: 咱们模仿 5 个用户吧:
用户 ID | mon | tue | wed | thur | fri | sat | sun |
---|---|---|---|---|---|---|---|
001 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
002 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
003 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
004 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
005 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
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 列表