Redis 中的 Bitmap
Redis 中一种非常高效的二进制数据结构。
核心是通过位(bit)来存储和操作数据,特别适合处理海量的布尔型(是 / 否)数据场景。
Bitmap 本质上是 Redis 的 String 类型 的「特殊使用方式」—— String 类型最大能存储 512MB 数据,对应可以存储 512MB * 8 = 4294967296 个位(约 43 亿位)。
Redis 的 String 类型 是二进制安全的字节序列,官方规定其最大存储容量为 512MB(字节);而 Bitmap 本质上是对 String 字节的「位级操作」—— 把每个字节(Byte)拆成 8 个位(Bit)来使用,因此 Bitmap 的最大可用位数 = 512MB × 8 = 4294967296 位(约 43 亿位)。
每个位只有 0 或 1 两种状态;
通过「偏移量(offset)」定位具体的位(偏移量从 0 开始,无上限,只要内存足够);
核心价值:用极少的内存存储海量的布尔型数据。
512MB 限制的底层原因
Redis 对 String 设 512MB 上限,并非技术上无法突破,而是基于「性能 + 设计定位」的权衡:
内存与性能平衡:String 是 Redis 最基础、使用最频繁的类型,若允许无限制存储大字符串,会导致:
单 key 占用过多内存。
读写大 String 时(如 GET/SET 512MB 数据),网络传输、内存拷贝耗时过长,阻塞 Redis 主线程;
符合 Redis 设计定位:Redis 是「内存数据库」,核心优势是「高速读写」,适合存储小而高频访问的数据(如缓存、计数器),而非大文件 / 大 blob 数据;
底层编码适配:Redis String 会根据长度自动切换编码(int→embstr→raw),超过 44 字节用 raw 编码,512MB 是 raw 编码的安全上限,避免编码切换或内存管理异常。
bitmap直观理解
比如用 Bitmap 记录「用户是否登录」:
offset = 用户 ID,value = 1(登录)/ 0(未登录);
记录 1 亿用户的登录状态,仅需 1亿 / 8 = 12.5MB 内存,远低于用 Hash/Set 等结构的内存消耗。
实际操作
所有命令都有 BIT
1. 设置指定偏移量的位值:SETBIT key offset value(重要)
作用:给 key 的第 offset 位设置值(0 或 1)
示例:记录用户 ID=10086 的用户今天(20260106)登录了(设为 1):
SETBIT login:20260106 10086 1
(integer) 0 # 返回值:该位原来的值(首次设置为0)
2 获取指定偏移量的位值:GETBIT key offset(重)
查询 key 的第 offset 位的值;
示例:查询用户 10086 20260106 是否登录:
GETBIT login:20260106 10086
3. 统计指定范围内值为 1 的位数量:(重)
BITCOUNT key [start end]
统计 key 中值为 1 的位的总数(可选指定字节范围,默认全部)
BITCOUNT login:20260106
4位运算(与 / 或 / 异或 / 非):BITOP operation destkey key1 [key2 ...]
作用:对多个 Bitmap 执行位运算,结果存入 destkey;
常用运算:
AND:与(都为 1 才为 1);
OR:或(任意一个为 1 则为 1);
XOR:异或(不同为 1,相同为 0);
示例:统计用户「20260105 和 20260106 两天都登录」的数量:
SETBIT login:20260105 10086 1
SETBIT login:20260105 10000 1
SETBIT login:20260106 10086 1
SETBIT login:20260106 10001 1
执行AND运算,结果存入 login:20260105_06_both
BITOP AND login:20260105_06_both login:20260105 login:20260106
统计结果(只有10086两天都登录)
BITCOUNT login:20260105_06_both
核心是通过位(bit)来存储和操作数据,特别适合处理海量的布尔型(是 / 否)数据场景。
Bitmap 本质上是 Redis 的 String 类型 的「特殊使用方式」—— String 类型最大能存储 512MB 数据,对应可以存储 512MB * 8 = 4294967296 个位(约 43 亿位)。
Redis 的 String 类型 是二进制安全的字节序列,官方规定其最大存储容量为 512MB(字节);而 Bitmap 本质上是对 String 字节的「位级操作」—— 把每个字节(Byte)拆成 8 个位(Bit)来使用,因此 Bitmap 的最大可用位数 = 512MB × 8 = 4294967296 位(约 43 亿位)。
每个位只有 0 或 1 两种状态;
通过「偏移量(offset)」定位具体的位(偏移量从 0 开始,无上限,只要内存足够);
核心价值:用极少的内存存储海量的布尔型数据。
512MB 限制的底层原因
Redis 对 String 设 512MB 上限,并非技术上无法突破,而是基于「性能 + 设计定位」的权衡:
内存与性能平衡:String 是 Redis 最基础、使用最频繁的类型,若允许无限制存储大字符串,会导致:
单 key 占用过多内存。
读写大 String 时(如 GET/SET 512MB 数据),网络传输、内存拷贝耗时过长,阻塞 Redis 主线程;
符合 Redis 设计定位:Redis 是「内存数据库」,核心优势是「高速读写」,适合存储小而高频访问的数据(如缓存、计数器),而非大文件 / 大 blob 数据;
底层编码适配:Redis String 会根据长度自动切换编码(int→embstr→raw),超过 44 字节用 raw 编码,512MB 是 raw 编码的安全上限,避免编码切换或内存管理异常。
bitmap直观理解
比如用 Bitmap 记录「用户是否登录」:
offset = 用户 ID,value = 1(登录)/ 0(未登录);
记录 1 亿用户的登录状态,仅需 1亿 / 8 = 12.5MB 内存,远低于用 Hash/Set 等结构的内存消耗。
实际操作
所有命令都有 BIT
1. 设置指定偏移量的位值:SETBIT key offset value(重要)
作用:给 key 的第 offset 位设置值(0 或 1)
示例:记录用户 ID=10086 的用户今天(20260106)登录了(设为 1):
SETBIT login:20260106 10086 1
(integer) 0 # 返回值:该位原来的值(首次设置为0)
2 获取指定偏移量的位值:GETBIT key offset(重)
查询 key 的第 offset 位的值;
示例:查询用户 10086 20260106 是否登录:
GETBIT login:20260106 10086
3. 统计指定范围内值为 1 的位数量:(重)
BITCOUNT key [start end]
统计 key 中值为 1 的位的总数(可选指定字节范围,默认全部)
BITCOUNT login:20260106
4位运算(与 / 或 / 异或 / 非):BITOP operation destkey key1 [key2 ...]
作用:对多个 Bitmap 执行位运算,结果存入 destkey;
常用运算:
AND:与(都为 1 才为 1);
OR:或(任意一个为 1 则为 1);
XOR:异或(不同为 1,相同为 0);
示例:统计用户「20260105 和 20260106 两天都登录」的数量:
SETBIT login:20260105 10086 1
SETBIT login:20260105 10000 1
SETBIT login:20260106 10086 1
SETBIT login:20260106 10001 1
执行AND运算,结果存入 login:20260105_06_both
BITOP AND login:20260105_06_both login:20260105 login:20260106
统计结果(只有10086两天都登录)
BITCOUNT login:20260105_06_both
全部评论
相关推荐
2025-12-23 19:23
东北大学 Java
我也不知道起什么名字...:拼多多18薪是有两个月的加班费,单休比双休一年多上大概两个月的班,所以就多了两个月的工资,这就是18薪的由来 点赞 评论 收藏
分享
