Redis中Bitmap的使用

优势

1.基于最小的单位bit进行存储,所以非常省空间。 

2.设置时候时间复杂度O(1)、读取时候时间复杂度O(n),操作是非常快的。 

3.二进制数据的存储,进行相关计算的时候非常快。 

4.方便扩容

限制

redis中bit映射被限制在512MB之内,所以最大是2^32位。建议每个key的位数都控制下,因为读取时候时间复杂度O(n),越大的串读的时间花销越多。

操作命令

setbit key offset value :对指定的key的value的指定偏移(offset)的位置1或0

GETBIT key offset : 获取offset设置的值,未设置过默认返回0

BITCOUNT key [start end]  :统计指定key位置为1的数量

Bit运算,BITOP 支持四种表达式运算:

AND(交集)

OR(并集)

XOR(异或)

NOT(取非)

bitmap的使用场景

总的来说就两种,以用户为例子:

1.一种是某一用户的横向扩展,即此个key值中记录这当前用户的各种状态值,允许无限扩展(2^32内)

点评:这种用法基本上是很少用的,因为每个key携带uid信息,如果存储的key的空间大于value,从空间角度看有一定的优化空间,如果是记录长尾的则可以考虑。

2.一种是某一用户的纵向扩展,即每个key只记录当前业务属性的状态,每个uid当作bit位来记录信息(用户超过2^32内需要分片存储)

例如:

1:一个拥有亿级数据量的短视频app,视频存在各种属性(是否加锁、是否特效等等),需要做各种标记。

2:用户在线状态,只需要一个key,然后用户id为偏移量offset,如果在线就设置为1,不在线就设置为0,3亿用户只需要36MB的空间

3:统计活跃用户,使用时间作为缓存的key,然后用户id为offset,如果当日活跃过就设置为1。之后通过bitOp进行二进制计算算出在某段时间内用户的活跃情况。

优化:

1.空间 

redis的bitmap已经是最小单位的存储了,有没有办法对二进制存储的信息再进行压缩呢?进一步省空间?

可以对记录的二进制数据进行压缩。常见的二进制压缩技术都是基于RLE(Run Length Encoding。对于一个很大的Bitmap,如果里边的数据分布很稀疏(说明有很多大片连续的0),采用RLE编码后,占用的空间会比原始的Bitmap小很多。

2.时间

redis虽然是在内存操作,但是超过redis指定存储在内存的阀值之后,会被搞到磁盘中。要是进行大范围的计算还需要从磁盘中取出到内存在计算比较耗时,效率也不高,有没有办法尽可能内存中多放一些数据,缩短时间?

采用RLE编码的Bitmap不需要进行解压缩,就可以直接进行AND/OR/XOR等各类计算;因此采用这类压缩技术的Bitmap,加载到内存后还是以压缩的方式存在,从而可以保证计算时候的低内存消耗;而采用word(计算机的字长,64位系统就是64bit)对齐等技术又保证了对CPU资源的高效利用。因此采用这类压缩技术的Bitmap,保持了Bitmap数据结构最重要的一个特性,就是高效的针对每个bit的逻辑运算。

常见的压缩技术包括 BBC(有专利保护),

发布了50 篇原创文章 · 获赞 2 · 访问量 2288

猜你喜欢

转载自blog.csdn.net/eafun_888/article/details/104714648