Redis Bitmap

Posted by icoding168 on 2020-04-17 12:19:08

分类: Redis  

Redis 的 Bitmap 是一种特殊的字符串,本质上它是一个数组,数组的每个元素都是一个 bit,只能存储 0 和 1。在 Bitmap 中,数组的下标叫做 offset(偏移量)。

Redis Bitmap 相关命令

SETBIT key offset value

对某个 key 设置指定偏移量上的 bit 为 0 或 1,当 key 不存在时,自动生成一个新的字符串。

字符串会进行扩展以确保它可以将 value 保存在指定的偏移量上,伸展时以 0 填充空白位置。offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。

GETBIT key offset

获取某个 key 指定偏移量上的 bit,当 offset 比字符串的长度大,或者 key 不存在时,返回 0 。

BITCOUNT key start end

计算给定字符串中,从 start 到 end 范围内被设置为 1 的比特位的数量。不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

Bitmap 的优点

  • 非常省内存
  • 能自动扩容
  • 读写速度快,读取时间复杂度O(n),写入时间复杂度O(1)

Bitmap 的应用场景

Bitmap 使用 0 和 1 表示信息,相比较于其他数据结构可以极大的节省存储空间,同时可以提供非常快的计算效率。在数据量较大又只关心是与否的场景下,非常适合用 Bitmap。

客户端心跳状态记录

共享单车的服务端需要知道共享单车的在线状态,共享单车每隔 1 秒向服务端发送信息,服务端收到后记录下来,表示共享单车在线,这也就是心跳检测机制。

一天有 86400 秒,假设共享单车有 10 万台,那么每天的心跳数据量会很大,如果使用 MySQL 来记录的话,MySQL 的负担也比较大。

以下是使用 Bitmap 的解决方案:

以共享单车的编号作为 key 来初始化一个容量为 86400 的 Bitmap,也就是说每台共享单车对应一个 Bitmap,然后服务端收到共享单车的心跳信息后,计算出当前时间是一天中的第几秒,以这个第几秒作为偏移量,然后设置 value 为 1 表示有心跳。

用户在线状态统计

Bitmap 用 1M 的空间就能拥有 8388608 个 bit,我们可以将用户的 id 映射为 Bitmp 的偏移量,用不到 1M 的空间就能存储百万用户的在线状态信息,用 BITCOUNT 命令就能得到当前在线用户数量。