- 关于Bitmaps的设计与实现,可以参阅:https://blog.csdn.net/qq_41453285/article/details/103501272
一、Bitmaps数据结构模型概述
- 现代计算机用二进制(位)作为信息的基础单位,1个字节等于8位。例 如“big”字符串是由3个字节组成,但实际在计算机存储时将其用二进制表 示,“big”分别对应的ASCII码分别是98、105、103,对应的二进制分别是01100010、01101001和01100111,如下图所示:
- Redis提供了Bitmaps这个“数据结构”可以实现对位的操作,但是:
- Bitmaps本身不是一种数据结构,实际上它就是字符串(如下图所示),但是它可以对字符串的位进行操作
- Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的 每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。
二、命令
- 下面演示案例中将每个独立用户是否访问过网站存放在Bitmaps中,将访问的用户记做1,没有访问的用户记做0,用偏移量作为用户的id
设置值(setbit)
setbit key offset value
- 用于为位数组指定偏移量(从0算起)上的二进制位设置值,并将之前二进制位的旧值返回
- 例如:
- 假设现在有20个用户, userid=0,5,11,15,19的用户对网站进行了访问,我们使用下面的命令将它们对应的位置为1
- 那么当前Bitmaps初始化结果如下图所示:
- 如果此时有一个userid=50的用户访问了网站,那么bitmaps的结果会自动变化,变为如下所示的样子:
- 很多应用的用户id以一个指定数字(例如10000)开头,直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费,通常的做法是每次做setbit 操作时将用户id减去这个指定数字。在第一次初始化Bitmaps时,假如偏移量非常大,那么整个初始化过程执行会比较慢,可能会造成Redis的阻
获取值(getbit)
getbit key offset
- 用于获取位数组指定偏移量上的二进制位的值
- 例如,接着上面的演示案例,我们获取第0索引和第8索引处的二进制位的值(0号为1,8号为0)
- 如果offset超出了bitmap的范围,那么也返回0。例如:
获取bitmaps内值为1的个数(bitcount)
bitcount [start] [end]
- 用于统计位数组里面,值为1的二进制位的数量。
- 参数的注意事项:
- start和end可以省略,如果省略那么遍历整个bitmaps
- start默认从0开始
- start和end的单位为字节数,而不是bit数(重点)
- 例如,接着上面的演示案例,因为bitmaps中有5个为被置为1,所以下面的命令返回5
- 下面遍历第2个字节到第3个字节之间bit为1的数目,结果显示3
bitmaps间的运算(BITOP)
bitop destkey key [key......]
- 可以对多个位数组进行按位与(and)、按位或(or)、按位异或(xor)、取反(not)
- 下面演示按位与(and)、按位或(or)、按位异或(xor)的操作
- 下面演示取反(not)的操作
计算Bitmaps中第一个值为targetBit的偏移量(bitpos)
bitpos key targetBit [start] [end]
- 参数注意事项:
- start和end可以省略,如果省略那么遍历整个bitmaps
- start默认从0开始
- start和end的单位为字节数,而不是bit数(重点)
- 例如,下面计算bitmaps中第一个值为1的bit位索引,结果显示为0
- 例如,下面在第2个字节和第3个字节之间计算bitmaps中第一个值为1的bit位索引和第一个值为0的bit位索引,结果分别显示为8和11
三、Bitmaps分析
- 假设网站有1亿用户,每天独立访问的用户有5千万,如果每天用集合类型和Bitmaps分别存储活跃用户(如下图所示)
- 很明显,这种情况下使用Bitmaps能节省很多的内存空间,尤其是随着时间推移节省的内存还是非常可观的,见下图
- 但Bitmaps并不是万金油,假如该网站每天的独立访问用户很少,例如只有10万(大量的僵尸用户),那么两者的对比如下图所示,很显然,这时候使用Bitmaps就不太合适了,因为基本上大部分位都是0
转载:https://blog.csdn.net/qq_41453285/article/details/106065718
查看评论