Redis特殊数据类型:Bitmap

Bitmap

一、类型概述

Bitmap(位图),也称为 Bit array(位数组)或 Bitset(位集合),并不是一种单独的数据结构,而是基于 Redis 的 String 类型实现的一种"位级别"的操作方式。

你可以把它想象成一个由 01 组成的数组,数组的每个单元只能存储 01,数组的索引(在 Redis 中称为 offset)从 0 开始。

核心要点:

  • 底层是 String:Bitmap 的本质是一个 String 值,它对应的是一个二进制的字节串。所以,所有针对 Bitmap 的命令,本质上都是对字符串值的二进制位进行操作。
  • 自动扩容:当你设置一个偏移量很大的位时,Redis 会自动分配内存并将中间未设置的位全部初始化为 0。
  • 极其节省空间:通过位来存储信息,一个字节(8 bits)可以存储 8 个独立的状态。例如,存储 1 亿用户的在线状态,只需要大约 12MB 的内存(1亿 / 8 / 1024 / 1024 ≈ 11.92MB)。

二、基本方法

1. 设置位值 SETBIT key offset value

bash 复制代码
127.0.0.1:6379> setbit log 0 1
(integer) 0  #返回指定偏移量原来存储的位,没有默认为0。
127.0.0.1:6379> setbit log 1 1
(integer) 0
127.0.0.1:6379> setbit log 2 1
(integer) 0
127.0.0.1:6379> setbit log 3 0
(integer) 0

2. 获取位值 GETBIT key offset

bash 复制代码
127.0.0.1:6379> getbit log 2
(integer) 1

3. 统计 BITCOUNT key [start end]

startend字节索引,而不是位索引。可以使用负数值,-1 表示最后一个字节,-2 表示倒数第二个字节。

bash 复制代码
127.0.0.1:6379> bitcount log  
(integer) 3  #位值位1的有三个

三、内部实现

正如概述中所说,Bitmap 的底层实现就是 Redis 的 String 数据类型。String 在 Redis 内部是以二进制安全的字节数组形式存储的。

当你执行 SETBIT key 10 1 时:

  1. Redis 会找到或创建一个与 key 关联的字符串值。
  2. 它会计算出第 10 位位于哪个字节(第 10 / 8 = 1 个字节,索引从 0 开始)以及在该字节中的哪一位(第 10 % 8 = 2 位)。
  3. 然后,它通过位运算(如按位或 | 和按位与 &)来设置或清除该特定位的值。
  4. 如果目标偏移量超出了当前字符串的长度,Redis 会扩展字符串,并用零字节填充中间的空隙。

四、应用场景

Bitmap 因其极致的空间效率和快速的位运算,在特定场景下表现非常出色。

1. 用户行为标记

这是最经典的应用场景。

  • 用户签到key 可以设计为 user:sign:202405:{uid},一位代表一天。SETBIT user:sign:202405:1001 20 1 表示用户 1001 在 5 月 21 日签到了。
  • 用户在线状态key 可以设计为 user:online:20240520,一位代表一个用户。SETBIT user:online:20240520 1001 1 表示用户 1001 今天在线。

2. 大数据量下的布尔统计

  • 活跃用户分析 :如上例,可以轻松统计每日活跃用户数(BITCOUNT)。通过 BITOP AND/OR,可以计算:

    • 连续活跃用户BITOP AND
    • 某段时间内的活跃用户BITOP OR
  • 特征标签筛选 :可以为每个特征(如"男性"、"喜欢编程"、"VIP用户")创建一个 Bitmap,每一位表示一个用户是否具有此特征。通过 BITOP AND 可以快速找到同时满足多个特征的用户群。

3. 布隆过滤器

Bitmap 是实现布隆过滤器的核心数据结构。布隆过滤器是一种概率型数据结构,用于高效地判断一个元素是否存在于一个集合中。它可能存在误判(判断一个不存在的元素为存在),但绝不会漏判(判断存在的元素一定存在),并且非常节省空间。

相关推荐
召摇3 小时前
Redis与PostgreSQL缓存性能终极对决:7千次/秒真的够用吗?
redis·postgresql·面试
帧栈5 小时前
开发避坑指南(61):Redis持久化失败:RDB快照因磁盘问题无法保存解决方案
数据库·redis·缓存
晨港飞燕5 小时前
Websocket+Redis实现微服务消息实时同步
redis·websocket·微服务
gsfl6 小时前
redis单线程模型
数据库·redis·缓存
hhh小张9 小时前
Redis基本数据类型:Hash
redis
Vahala0623-孔勇10 小时前
分布式锁巅峰对决:Redis RedLock vs ZooKeeper临时节点——Redission看门狗如何破解续期困局
redis·分布式·zookeeper
gsfl11 小时前
Redis List 类型全解析
数据库·redis·list
宸津-代码粉碎机12 小时前
Redis 进阶:跳出缓存局限!7 大核心场景的原理与工程化实践
java·人工智能·redis·python
我是苏苏19 小时前
Redis开发07:使用stackexchange.redis库实现简单消息队列
数据库·redis·缓存