CodeWalk

RoaringBitmap原理与大数据去重

作者:我是大山 · 2026-05-30 12:55

什么是RoaringBitmap?请说明其数据结构和存储优化原理。相比传统BitMap,RoaringBitmap在稀疏和稠密场景下各有哪些优势?在StarRocks/Druid/Kylin中如何应用RoaringBitmap实现精确去重和加速计算?

回答

我是大山

1. RoaringBitmap原理

RoaringBitmap将32位整数空间分为高16位低16位

Key(高16位)       Container
    ↓                 ↓
   0x0001    →    ArrayContainer(稀疏,存低16位列表)
   0x0002    →    BitmapContainer(稠密,位图)
   0x0003    →    RunContainer(连续范围,变长编码)

三种Container

容器类型存储方式适用场景内存占用
ArrayContainershort[] 有序数组元素<4096个2*N bytes
BitmapContainer8KB位图元素≥4096个8KB固定
RunContainer(start, len)对连续大区间2*RLE对 bytes

2. 优势对比

场景传统BitMapRoaringBitmap
稀疏(1%填充)8KB固定240962=16KB...但优于N=1时2bytes
稠密(90%填充)8KB固定BitmapContainer=8KB(相同)
压缩(连续)8KB固定RunContainer可压缩到几百bytes
AND/OR运算O(n)位运算智能选择Container类型优化

3. 大数据应用

StarRocks精确去重

-- Bitmap类型列
CREATE TABLE user_visit (
  dt DATE,
  user_id BITMAP BITMAP_UNION
) AGGREGATE KEY(dt);

-- 查询
SELECT dt, bitmap_count(user_id) FROM user_visit;
SELECT bitmap_count(bitmap_union(user_id)) FROM user_visit;

Druid

  • 使用RoaringBitmap实现精确去重
  • 支持跨维度Bitmap运算(交/并/差)

Kylin

  • 预计算中Bitmap精确去重度量
  • 支持IntersectCount

4. 性能对比

1亿用户ID去重:
HyperLogLog:1.2MB(误差2-3%)
RoaringBitmap:≈120MB(精确)
原始BitMap:512MB
普通HashSet:3.2GB+

5. 适用场景

  • 精确UV统计(用户数≤10亿)
  • 画像分析(标签交并运算)
  • 漏斗分析(每一步去重)
  • 广告归因(多维度明细交集)