企业级Redis开发运维从入门到实践 (12)— Bitmap(位图)
位图结构
以位图的形式写入,取出数据进行查看
redis> set hello big
OK
redis> getbit hello 0
(integer) 0
reids> getbit hello 1
(integer) 1
所以得出下图的结构,其实Redis是可以直接操作位的,这就是Redis的位图功能。
位图相关命令
setbit
- setbit key offset value:给位图指定索引设置值。
- 时间复杂度:O(1)。
# 返回值是指定偏移量原来储存的位。
redis> setbit unique:users:2016-04-05 0 1
(integer) 0
redis> setbit unique:users:2016-04-05 5 1
(integer) 0
redis> setbit unique:users:2016-04-05 11 1
(integer) 0
redis> setbit unique:users:2016-04-05 15 1
(integer) 0
redis> setbit unique:users:2016-04-05 19 1
(integer) 0
以上操作后,位图中的结果是下图结构,下标(索引)为0、5、11、15、19的值都已变成了1。
如果只设置索引50,则位图将变为:
getbit
- getbit key offset:获取位图指定索引的值。
- 时间复杂度:O(1)。
# 返回值是字符串值指定偏移量上的位(bit)。
redis> getbit unique:users:2016-04-05 8
(integer) 0
redis> getbit unique:users:2016-04-05 19
(integer) 1
bitcount
- bitcount key [start end]:获取位图指定范围( start 到 end ,单位为字节,如果不指定就是获取全部)位值为1的个数。
- 时间复杂度:O(N)。
redis> bitcount unique:users:2016-04-05
(integer) 5
redis> bitcount unique:users:2016-04-05 1 3
(integer) 3
bitop
- bitop op destkey key [key…]:做多个Bitmap 的 and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在 destkey 中。
- 时间复杂度:O(N)。
# 返回值:保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。
# 求两个位图的并集
redis> bitop and unique:users:and:2016_04_04-2016_04_05 unique:users:2016-04-05 unique:users:2016-04-04
(integer) 3
redis> bitcount unique:users:and:2016_04_04-2016_04_05
(integer) 2
bitpos
- bitpos key targetBit [start] [end]:计算位图指定范围( start 到 end,单位为字节,如果不指定就是获取全部)第一个偏移量对应的值等于targetBit的位置。
- 时间复杂度:O(N)。
redis> bitpos unique:users:2016-04-04 1
(integer) 1
redis> bitpos unique:users:2016-04-04 0 1 2
(integer) 8
应用场景
独立用户统计
- 使用set和Bitmap
- 1亿用户,5千万独立
数据类型 | 每个userid占用空间 | 需要存储的用户量 | 全部内存存储量 |
---|---|---|---|
set | 32位(假设userid用的是整型,实际很多网站用的是长整型) | 50,000,000 | 32位 * 50,000,000 = 200MB |
Bitmap | 1位 | 100,000,000 | 1位 * 100,000,000 = 12.5MB |
一天 | 一个月 | 一年 | |
---|---|---|---|
set | 200M | 6G | 72G |
Bitmap | 12.5M | 375M | 4.5G |
- 只有10万独立用户
数据类型 | 每个userid占用空间 | 需要存储的用户量 | 全部内存存储量 |
---|---|---|---|
set | 32位(假设userid用的是整型,实际很多网站用的是长整型) | 1,000,000 | 32位 * 1,000,000 = 4MB |
Bitmap | 1位 | 100,000,000 | 1位 * 100,000,000 = 12.5MB |
使用经验
- type = string,最大512MB
- 注意setbit时的偏移量,可能有较大耗时
- 位图不是绝对好