一、bitmap是什么?
redis原文:
Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type . This means that bitmaps can be used with string commands, and most importantly with SET and GET.
翻译过来是:
位图不是一种实际的数据类型,而是在String类型上定义的一组面向位的操作(有关更多信息,请参阅数据类型简介页面的“位图”部分)。这意味着位图可以用于字符串命令,还可以用SET和GET命令来进行操作。
二、bitmap有哪些优势?
Bitmap的优势在于其基于最小的单位bit进行存储,非常节省空间。设置和读取操作的时间复杂度为O(1),即非常快速。此外,二进制数据的存储和计算也非常快,适合用于需要高速读写和统计的操作。
三、bitmap能存储多大?
官方文档介绍,bitmap能操作的最大偏移量是2^32,所以这里也限制了bitmap的最大容量为512MB,而且最后设置的位如果快到了2的32次方,那么就可能会存在阻塞的情况,下面是官方文档的原文
When key does not exist, a new string value is created. The string is grown to make sure it can hold a bit at offset. The offset argument is required to be greater than or equal to 0, and smaller than 2^32 (this limits bitmaps to 512MB). When the string at key is grown, added bits are set to 0.
Warning: When setting the last possible bit (offset equal to 2^32 -1) and the string value stored at key does not yet hold a string value, or holds a small string value, Redis needs to allocate all intermediate memory which can block the server for some time. On a 2010 MacBook Pro, setting bit number 2^32 -1 (512MB allocation) takes ~300ms, setting bit number 2^30 -1 (128MB allocation) takes ~80ms, setting bit number 2^28 -1 (32MB allocation) takes ~30ms and setting bit number 2^26 -1 (8MB allocation) takes ~8ms. Note that once this first allocation is done, subsequent calls to SETBIT for the same key will not have the allocation overhead。
四、bitmap应用场景
1. 用户签到
可以使用 Bitmap 来记录用户的签到情况,每个用户作为键名,每天的日期对应一个位。若用户签到,就将对应的位置为 1;若未签到,则置为 0。通过这种方式,能够方便地统计用户的签到次数、连续签到天数等信息。
2. 在线状态统计
记录用户的在线状态,每个用户对应一个位,若用户在线,就将对应的位置为 1;若离线,则置为 0。这样可以快速统计当前在线的用户数量。
五、bitmap常用命令有哪些?
官网命令介绍
Commands | Docs
https://redis.io/docs/latest/commands/?group=bitmap
1. SETBIT
- 功能:设置指定键的 Bitmap 中指定偏移量的位的值。
- 语法:
SETBIT key offset value
- 示例:
SETBIT user_sign:20250507 10 1
这个命令将 user_sign:20250507
这个键对应的 Bitmap 中偏移量为 10 的位的值设置为 1。
返回值:该位设置之前的值。 offset从1开始。
2. GETBIT
- 功能:获取指定键的 Bitmap 中指定偏移量的位的值。
- 语法:
GETBIT key offset
- 示例:
GETBIT user_sign:20250507 10
这个命令会返回 user_sign:20250507
这个键对应的 Bitmap 中偏移量为 100 的位的值。
3. BITCOUNT
- 功能:统计指定键的 Bitmap 中值为 1 的位的数量。
- 语法:
BITCOUNT key [start end]
- 示例:
BITCOUNT user_sign:20250507
这个命令会统计 user_sign:20250507
这个键对应的 Bitmap 中值为 1 的位的数量。
4. BITOP
- 功能:对一个或多个 Bitmap 进行位运算(如 AND、OR、XOR、NOT),并将结果存储在指定的键中。
- 语法:
BITOP operation destkey key [key ...]
- 示例:
BITOP AND result user_sign:20250506 user_sign:20250507
这个命令会对 user_sign:20250506
和 user_sign:20250507
这两个键对应的 Bitmap 进行按位与运算,并将结果存储在 result
这个键中。
5. BITPOS
- 功能:查找指定键的 Bitmap 中第一个值为指定值(0 或 1)的位的偏移量。
- 语法:
BITPOS key bit [start [end]]
- 示例:
BITPOS user_sign:20250507 1
这个命令会查找 user_sign:20250507
这个键对应的 Bitmap 中第一个值为 1 的位的偏移量。
6. BITFIELD
Redis 的 BITFIELD
命令提供了一种强大且灵活的方式来操作位图(bitmap)。它允许你在单个命令中对一个或多个位域(bit field)进行操作,包括获取和设置指定位域的值,支持不同的编码方式(如有符号整数和无符号整数),还能处理溢出情况。这使得 BITFIELD
非常适合处理复杂的位操作需求,例如处理用户的多个状态标志或者进行高效的数值存储。
详见官网或者豆包。
7. BITFIELD_RO
BITFIELD_RO
是 Redis 中用于操作位图(bitmap)的只读命令。与 BITFIELD
命令类似,它允许你从位图中获取指定位域(bit field)的值,支持以不同的数据类型(如无符号整数、有符号整数)来解释这些位域。不过,BITFIELD_RO
只能用于读取操作,不能进行写入操作(如设置位域的值、增加位域的值等),这使得它在只需要获取位图信息而不修改位图的场景下使用,能避免意外的数据修改。
详见官网或者豆包。