摘要
RoaringBitmap 命令
-
可以在 redis-cli 中执行 help @module,找出所有 R.* 和 R64.* 的命令说明
-
R.*:操作的是 32 位无符号整数(最大约 2^32-1)
-
R64.*:操作的是 64 位无符号整数(最大约 2^64-1),适合超大 ID 空间,如 Snowflake / 时间戳映射
R64.* 支持的整数理论上是 0 ~ 2⁶⁴-1(约 1.84e19),但工程上应谨慎使用超大 offset,避免稀疏爆炸和性能退化。
1 2 3 4 5 6 7 8 9 10
| high 32 bits -> container key 大桶 low 32 bits -> container offset 小桶
当你写入一个非常大的值,例如 10^18 虽然 Roaring 只为存在数据的 container 分配内存。 但 container 的 key 本身是一个 map / array 索引结构。 极端稀疏、超大 offset 会增加索引管理成本,会导致某些命令操作会变得很慢。 另外,一个容器至少要 几十字节 ~ 几百字节级别,容器的数量过多,单机内存也无法满足 如果你创建 10 亿个 container,假设每个 container 占用 100 字节,那么内存占用为: 10^9 containers × 100 bytes ≈ 100 GB 内存
|
-
两者语义完全一致,仅支持的 offset 范围不同,以下示例以 R.* 为主。
-
对比 R 与 R64
| 维度 |
R.* |
R64.* |
| Offset 类型 |
uint32 |
uint64 |
| 最大值 |
4,294,967,295 (~4.29e9) |
18,446,744,073,709,551,615 (~1.84e19) |
| 可表达规模 |
十亿级 |
万亿亿级 |
| 典型用途 |
用户ID、索引 |
时间戳、雪花ID、全局唯一ID |
一、数据写入 / 修改类
| 命令 |
功能 |
典型用途 |
示例 |
| R.SETBIT |
设置单个 bit(0/1),返回旧值 |
单点标记 |
R.SETBIT users 1001 1 |
| R.SETRANGE |
批量设置区间 bit=1 |
连续区间打标 |
R.SETRANGE users 3000 3999,不包含3999 |
| R.APPENDINTARRAY |
追加多个整数(bit=1) |
批量插入 ID |
R.APPENDINTARRAY users 1001 1002 1003 |
| R.SETINTARRAY |
用整数数组重建 bitmap |
初始化数据 |
R.SETINTARRAY users 1 3 5 7 |
| R.SETBITARRAY |
用 bit 字符串重建 bitmap |
外部导入 |
R.SETBITARRAY users "101001" |
| R.DELETEINTARRAY |
删除多个整数(bit=0) |
批量删除 |
R.DELETEINTARRAY users 1002 2000 |
| R.CLEARBITS |
清除指定 offset |
精确清理 |
R.CLEARBITS users 1001 1003 |
| R.SETFULL |
填充整个 bitmap |
全量初始化 |
R.SETFULL users |
| R.CLEAR |
删除整个 bitmap |
释放资源 |
R.CLEAR users |
二、数据读取 / 查询类
| 命令 |
功能 |
典型用途 |
示例 |
| R.GETBIT |
获取单个 bit |
判断是否存在 |
R.GETBIT users 1001 |
| R.GETBITS |
批量获取 bit |
多点查询 |
R.GETBITS users 1001 1002 1003 |
| R.GETBITARRAY |
返回完整 bit 字符串 |
调试 / 导出 |
R.GETBITARRAY users |
| R.GETINTARRAY |
返回所有为 1 的整数 |
全量遍历 |
R.GETINTARRAY users |
| R.RANGEINTARRAY |
返回区间内整数,注意这里参数是索引下标,不是数值 |
分页扫描 |
R.RANGEINTARRAY users 1 5 |
| R.MIN |
最小 offset |
最小 ID 查询 |
R.MIN users |
| R.MAX |
最大 offset |
最大 ID 查询 |
R.MAX users |
三、统计类
| 命令 |
功能 |
典型用途 |
示例 |
| R.BITCOUNT |
bit=1 数量统计 |
集合基数 |
R.BITCOUNT users |
| R.BITPOS |
查找第一个 1 或 0 |
稀疏分析 |
R.BITPOS users 1 |
| R.MIN |
最小 bit 位置 |
边界检测 |
R.MIN users |
| R.MAX |
最大 bit 位置 |
边界检测 |
R.MAX users |
| R.STAT |
容器 / 内存统计 |
性能调优 |
R.STAT users TEXT |
四、集合运算类
| 命令 |
功能 |
集合语义 |
示例 |
| R.BITOP AND |
位图交集 |
A ∩ B |
R.BITOP AND res a b |
| R.BITOP OR |
位图并集 |
A ∪ B |
R.BITOP OR res a b |
| R.BITOP XOR |
对称差集 |
A ⊕ B |
R.BITOP XOR res a b |
| R.DIFF |
差集 |
A - B |
R.DIFF res a b |
| R.CONTAINS |
包含关系判断 |
子集检测 |
R.CONTAINS a b ALL |
| R.JACCARD |
相似度计算 |
J(A,B) |
R.JACCARD a b |
五、维护 / 优化类
| 命令 |
功能 |
典型用途 |
示例 |
| R.OPTIMIZE |
容器重整 / 压缩 |
降低内存 |
R.OPTIMIZE users MEM |
| R.CLEAR |
清理 bitmap |
回收资源 |
R.CLEAR users |
六、R / R64 对照表(含示例)
| 功能 |
R (32bit) |
R64 (64bit) |
示例 |
| 设置 bit |
R.SETBIT |
R64.SETBIT |
R64.SETBIT users64 90000000000 1 |
| 批量插入 |
R.APPENDINTARRAY |
R64.APPENDINTARRAY |
R64.APPENDINTARRAY users64 90000000001 90000000002 |
| 查询 bit |
R.GETBIT |
R64.GETBIT |
R64.GETBIT users64 90000000001 |
| 统计 |
R.BITCOUNT |
R64.BITCOUNT |
R64.BITCOUNT users64 |
| 集合运算 |
R.BITOP |
R64.BITOP |
R64.BITOP OR res64 a64 b64 |
| 优化 |
R.OPTIMIZE |
R64.OPTIMIZE |
R64.OPTIMIZE users64 MEM |
真实案例
1 2 3 4 5 6 7 8 9 10 11 12
| 假设我们有一个电商平台,需要统计以下指标: VIP 用户(购买金额超过 1000 的用户) 付费用户(至少购买一次的用户) 最近活跃用户(过去 7 天内登录过的用户)
我们想要计算: VIP 用户人数 VIP 且最近活跃的用户人数 VIP 且付费用户且最近活跃的人数 付费用户与最近活跃用户的 Jaccard 相似度
假设用户 ID 为整数(最大值 < 2^32,使用 R.* 即可)。
|
1 2 3 4 5 6 7 8 9 10 11 12
| R.APPENDINTARRAY vip_users 1001 1002 1003 1004 1005
R.APPENDINTARRAY paid_users 1002 1003 1005 1006 1007
R.APPENDINTARRAY active_users 1001 1003 1005 1008
127.0.0.1:6379> type active_users reroaring
|
1 2 3 4 5 6 7 8 9 10 11
| R.BITCOUNT vip_users
R.BITCOUNT active_users
R.BITCOUNT paid_users
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| R.BITOP AND vip_active vip_users active_users R.BITCOUNT vip_active
R.BITOP AND vip_paid vip_users paid_users
R.BITOP AND vip_paid_active vip_paid active_users R.BITCOUNT vip_paid_active
|
1 2 3 4 5 6
| R.JACCARD paid_users active_users
J(A, B) = |A ∩ B| / |A ∪ B| = 交集 / 并集 0.2857142857142857 = |1003, 1005| / |1001, 1002, 1003, 1005, 1006, 1007, 1008| = 2 / 7 = 0.2857142857142857
|
J(A,B)=∣A∪B∣∣A∩B∣
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| R.GETINTARRAY vip_users
1) (integer) 1001 2) (integer) 1002 3) (integer) 1003 4) (integer) 1004 5) (integer) 1005
R.RANGEINTARRAY active_users 1 3
1) (integer) 1003 2) (integer) 1005 3) (integer) 1008
|
1 2 3 4
| R.OPTIMIZE vip_users MEM R.OPTIMIZE paid_users MEM R.OPTIMIZE active_users MEM
|