BitMap 是 Redis 2.2.0 版本中引入的一种新的数据类型。该数据类型本质上就是一个仅包含 0 和 1 的二进制字符串。而其所有相关命令都是对这个字符串二进制位的操作。用于描述该字符串的属性有三个:key、offset、bitValue。
- key:BitMap 是 Redis 的 key-value 中的一种 Value 的数据类型,所以该 Value 一定有其对应的 key。
- offset:每个 BitMap 数据都是一个字符串,字符串中的每个字符都有其对应的索引,该索引从 0 开始计数。该索引就称为每个字符在该 BitMap 中的偏移量 offset。这个 offset的值的范围是[0,232-1],即该 offset 的最大值为 4G-1,即 4294967295,42 亿多。
- bitValue:每个 BitMap 数据中都是一个仅包含 0 和 1 的二进制字符串,每个 offset 位上的字符就称为该位的值 bitValue。bitValue 的值非 0 即 1。
应用场景
由于 offset 的取值范围很大,所以其一般应用于大数据量的二值性统计。例如平台活跃
用户统计(二值:访问或未访问)、支持率统计(二值:支持或不支持)、员工考勤统计(二
值:上班或未上班)、图像二值化(二值:黑或白)等。
不过,对于数据量较小的二值性统计并不适合 BitMap,可能使用 Set 更为合适。当然,
具体多少数据量适合使用 Set,超过多少数据量适合使用 BitMap,这需要根据具体场景进行
具体分析。例如,一个平台要统计日活跃用户数量。
如果使用 Set 来统计,只需上线一个用户,就将其用户 ID 写入 Set 集合即可,最后只需
统计出 Set 集合中的元素个数即可完成统计。即 Set 集合占用内存的大小与上线用户数量成
正比。假设用户 ID 为 m 位 bit 位,当前活跃用户数量为 n,则该 Set 集合的大小最少应该是
mn 字节。
如果使用 BitMap 来统计,则需要先定义出一个 BitMap,其占有的 bit 位至少为注册用
户数量。只需上线一个用户,就立即使其中一个 bit 位置 1,最后只需统计出 BitMap 中 1 的
个数即可完成统计。即 BitMap 占用内存的大小与注册用户数量成正比,与上线用户数量无
关。假设平台具有注册用户数量为 N,则 BitMap 的长度至少为 N 个 bit 位,即 N/8 字节。
何时使用 BitMap 更合适?令 mn 字节 = N/8 字节,即 n = N/8/m = N/(8m) 时,使用
Set 集合与使用 BitMap 所占内存大小相同。以淘宝为例,其用户 ID 长度为 11 位(m),其注
册用户数量为 8 亿(N),当活跃用户数量为 8 亿/(811) = 0.09 亿 = 9*106= 900 万,使用 Set与 BitMap 占用的内存是相等的。但淘宝的日均活跃用户数量为 8 千万,所以淘宝使用 BitMap更合适.