Redis位图
位图(Bitmap)不是独立的数据类型,而是字符串类型的位操作扩展,支持高效的位级操作,适合统计、标记等场景。
结构概述
基本特点
Bash
- 字符串的位级操作扩展
- 每个bit可存储0或1
- 最大支持2^32个位(约512MB)
- 极节省内存空间
- 位操作原子性
位图示意
Bash
字符串:存储字节数组
位图:操作每个字节中的8个bit
字节0: [bit0][bit1][bit2][bit3][bit4][bit5][bit6][bit7]
字节1: [bit8][bit9][bit10][bit11][bit12][bit13][bit14][bit15]
...
每个bit可独立设置和获取
内存计算
Bash
1位 = 1bit
8位 = 1字节
1亿用户签到 ≈ 12.5MB(每用户1位)
对比传统存储:
Set存储1亿用户ID ≈ 数百MB
Bitmap存储1亿用户标记 ≈ 12.5MB
核心命令
SETBIT设置位
Bash
# 设置第offset位为value(0或1)
SETBIT key offset value
# 设置用户1000已签到(offset=1000)
SETBIT signin:2024:01:01 1000 1
# 返回:设置前的值(0或1)
GETBIT获取位
Bash
# 获取第offset位的值
GETBIT key offset
# 检查用户1000是否签到
GETBIT signin:2024:01:01 1000
# 返回: 1 或 0
BITCOUNT统计位
Bash
# 统计值为1的位数量
BITCOUNT key [start end]
# 统计全部
BITCOUNT signin:2024:01:01
# 返回: 签到总人数
# 统计字节范围
BITCOUNT signin:2024:01:01 0 1000
# 统计前1001个字节中的1位数
BITPOS查找位
Bash
# 查找第一个值为bit的位置
BITPOS key bit [start end]
# 查找第一个签到用户
BITPOS signin:2024:01:01 1
# 返回: 第一个1的位置
# 查找第一个未签到用户
BITPOS signin:2024:01:01 0
BITOP位运算
Bash
# 位运算(AND/OR/XOR/NOT)
BITOP operation destkey key [key ...]
# 交集运算
BITOP AND result set1 set2
# set1和set2都为1的位
# 并集运算
BITOP OR result set1 set2
# set1或set2为1的位
# 异或运算
BITOP XOR result set1 set2
# 取反运算
BITOP NOT result set1
BITFIELD位域操作
Bash
# 复杂位操作(Redis 3.2+)
BITFIELD key [GET type offset]
BITFIELD key [SET type offset value]
BITFIELD key [INCRBY type offset increment]
# 获取8位无符号整数(offset=0)
BITFIELD mykey GET u8 0
# 设置5位有符号整数
BITFIELD mykey SET i5 100 -3
# 自增操作
BITFIELD mykey INCRBY u4 0 1
应用场景
1. 用户签到
Bash
# 设置签到(用户ID为offset)
SETBIT signin:2024:01:01 1000 1
# 检查签到状态
GETBIT signin:2024:01:01 1000
# 统计当日签到人数
BITCOUNT signin:2024:01:01
# 统计连续签到
BITOP AND result signin:2024:01:01 signin:2024:01:02 signin:2024:01:03
BITCOUNT result
# 连续3天签到的人数
2. 活跃用户统计
Bash
# 记录每日活跃用户
SETBIT active:2024:01:01 user_id 1
# 统计活跃用户数
BITCOUNT active:2024:01:01
# 统计周活跃用户
BITOP OR weekly:active active:2024:01:* (7天)
BITCOUNT weekly:active
3. 用户在线状态
Bash
# 设置用户在线
SETBIT online:user 1000 1
# 设置用户离线
SETBIT online:user 1000 0
# 检查用户在线
GETBIT online:user 1000
# 统计在线用户
BITCOUNT online:user
4. 用户标签/属性
Bash
# 用户是否VIP(offset=0)
SETBIT user:attr:1000 0 1
# 用户是否活跃(offset=1)
SETBIT user:attr:1000 1 1
# 用户是否验证(offset=2)
SETBIT user:attr:1000 2 0
# 获取全部属性
GET user:attr:1000
5. 布隆过滤器(简单实现)
text
# 多个哈希函数设置位
SETBIT bloom:user 100 1
SETBIT bloom:user 200 1
SETBIT bloom:user 300 1
# 检查可能存在
GETBIT bloom:user 100
GETBIT bloom:user 200
GETBIT bloom:user 300
# 全为1则可能存在
内存效率对比
存储1亿用户标记
| 方式 | 内存占用 |
|---|---|
| Set存储用户ID | 约200MB+ |
| Bitmap存储标记 | 约12.5MB |
| 节省 | 约16倍 |
使用建议
text
用户ID密集时:Bitmap高效
用户ID稀疏时:Bitmap浪费内存(空位也占空间)
用户ID范围:建议从0开始连续编号
性能特点
操作效率
text
SETBIT/GETBIT:O(1)
BITCOUNT:O(N)(N为字符串长度)
BITOP:O(N)
内存分配
text
# 设置高位时Redis会扩展字符串
SETBIT key 1000000 1
# 扩展字符串到125KB(1000000/8字节)
# 大偏移量导致内存分配
# 注意偏移量范围
注意事项
用户ID偏移量
text
用户ID作为偏移量
- 用户ID从0开始最优
- 用户ID不连续时浪费内存
- 稀疏用户ID不适合Bitmap
内存扩容
text
# 设置大偏移量会扩展字符串
SETBIT sparse 1000000000 1
# 分配约125MB内存
# 稀疏位图浪费内存
字节范围
text
BITCOUNT start end是字节偏移
不是位偏移
start=0, end=0表示第一个字节(bit0-bit7)
与Set对比
| 特性 | Bitmap | Set |
|---|---|---|
| 存储内容 | 位标记 | 元素本身 |
| 内存效率 | 极高(密集) | 中 |
| 查找效率 | O(1) | O(1) |
| 运算支持 | AND/OR/XOR | SINTER/SUNION/SDIFF |
| 适用场景 | 密集ID标记 | 稀疏ID、元素存储 |
要点总结
- 位图是字符串的位操作扩展,每个bit存储0或1
- SETBIT/GETBIT设置和获取单个位,O(1)操作
- BITCOUNT统计值为1的位数量
- BITOP支持AND/OR/XOR/NOT位运算
- 应用场景:签到、活跃统计、在线状态、用户属性
- 用户ID密集时Bitmap极省内存(12.5MB存1亿用户)
- 用户ID稀疏时浪费内存,不适合Bitmap
- 大偏移量设置会导致内存扩展,注意范围
- BITFIELD支持复杂位域操作(Redis 3.2+)
📝 发现内容有误?点击此处直接编辑