全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-12 8 分钟 ✍️ juanwangdev

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对比

特性BitmapSet
存储内容位标记元素本身
内存效率极高(密集)
查找效率O(1)O(1)
运算支持AND/OR/XORSINTER/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+)

📝 发现内容有误?点击此处直接编辑

下一篇 → Redis列表
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库