StarRocks 存储引擎设计深度调研笔记

一、Tablet/Replica 架构

1.1 数据层级结构

StarRocks 数据组织层级:Table → Partition → Bucket (Tablet) → Replica → Rowset → Segment

  • Table: 逻辑表,由一个或多个 Partition 组成
  • Partition: 按分区键划分的数据子集,支持表达式分区(v3.0+,推荐)、Range分区(Legacy)、List分区(Legacy)
  • Bucket (Tablet): 分区内按分桶策略划分的最小数据分片,也是数据复制、迁移、均衡的最小单位
  • Replica: Tablet 的副本,默认 3 副本,确保数据可靠性
  • Rowset: 一次数据导入生成的数据版本文件集合,一个 Tablet 包含多个 Rowset
  • Segment: Rowset 内的数据段文件,列式存储的基本单位

1.2 分桶策略

策略 说明 适用场景
Random Bucketing (v3.1+默认) 随机分桶,无需指定 HASH 键 通用场景,简化建表
Hash Bucketing 按 HASH 键分桶,相同键值路由到同一桶 需要局部数据聚合的 Join/Agg
Range + Hash Range分区 + Hash分桶 时序+维度场景
List + Hash List分区 + Hash分桶 枚举值+维度场景

1.3 副本管理

  • 默认 3 副本(replication_num = 3
  • Shared-nothing 模式: 副本存储在 BE 本地磁盘
  • Shared-data 模式: 数据存储在对象存储/HDFS,本地仅缓存
  • 副本是数据复制、迁移、均衡的最小单位
  • FE 负责副本调度和均衡策略

1.4 设计取含

决策 原因
Tablet 作为最小调度单位 细粒度均衡,避免大表迁移开销
默认 3 副本 平衡数据可靠性与存储成本
Hash 分桶 相同键值本地聚合,减少网络 Shuffle
Random 分桶(v3.1+) 简化建表,自动均匀分布

关键参数 : PARTITION BY, DISTRIBUTED BY HASH, BUCKETS, replication_num

参考: https://docs.starrocks.io/docs/table_design/data_distribution


二、Segment 存储格式(列式页面、Zone Map、索引)

2.1 Segment 文件结构

一个 Segment 文件是列式存储的基本单元,包含以下部分:

复制代码
Segment 文件
├── Data Region(数据区)
│   └── 每列的 Data Pages(默认 64KB / page)
├── Index Region(索引区)
│   ├── Ordinal Index(行号 → Data Page 物理地址映射)
│   ├── Zone Map Index(每列每个 Data Chunk 的 Min/Max/HasNull/HasNotNull)
│   ├── Bitmap Index(可选,按列存储)
│   ├── Bloom Filter Index(可选,按列存储)
│   └── Prefix Index(排序键前缀索引)
├── Footer
│   ├── 各列索引的偏移量
│   ├── Segment 元信息
│   └── Footer 长度 & 魔数

2.2 列式 Data Page

  • Data Page 大小 : 默认 64KB(data_page_size = 64 * 1024
  • 每列数据独立存储在各自的 Data Pages 中(纯列存)
  • v3.2+ 支持行列混合存储"storage_format" = "native"),行列混合 Page 适用于点查询场景
  • Data Page 内数据按排序键有序排列
  • 数据经压缩后存储(LZ4/ZSTD/zlib/Snappy)

2.3 Ordinal Index(序号索引)

  • 内置自动索引,无需手动创建
  • 每个 Data Page 生成一条 Ordinal Index 条目,记录起始行号
  • 功能:通过行号定位列 Data Page 的物理地址
  • 实现从逻辑行号到物理 Page 偏移的映射

2.4 Data Chunk

  • 数据按排序键排序后,每 1024 行组成一个逻辑数据块(Data Chunk)
  • Zone Map 按 Data Chunk 维度存储统计信息
  • Prefix Index 按 Data Chunk 维度构建索引条目

2.5 设计取含

决策 原因
64KB Data Page 平衡 IO 效率与内存使用,适配列式压缩
每 1024 行一个 Chunk Zone Map 和 Prefix Index 的最小粒度,过滤效率与索引大小平衡
列式存储 高压缩比、按列读取、向量化执行友好
行列混合(v3.2+) 点查询场景减少 IO 放大

参考: https://docs.starrocks.io/docs/table_design/indexes / https://docs.starrocks.io/docs/table_design/data_compression


三、数据写入过程(MemTable → Flush → Compaction)

3.1 写入全流程

复制代码
数据写入请求
    ↓
1. FE 接收 Load 请求,生成 LoadJob,分配事务 ID
    ↓
2. BE 接收数据,写入 MemTable(内存中的排序树)
    ↓
3. MemTable 满(达到阈值),Flush 到磁盘生成 Rowset(一个版本的数据文件集合)
    ↓
4. Rowset 包含多个 Segment 文件(列式存储)
    ↓
5. 事务 Publish,数据可见
    ↓
6. 后台 Compaction 合并多个 Rowset

3.2 MemTable 阶段

  • 数据写入 BE 时,首先进入内存中的 MemTable
  • MemTable 是一个排序树结构(SkippableList),数据按排序键有序插入
  • 在写入过程中,相同键的数据按表模型进行合并:
    • Duplicate Key: 不合并,全部保留
    • Aggregate Key: 按聚合函数合并(SUM/MAX/MIN/REPLACE等)
    • Unique Key: 追加写入,不做在线合并
    • Primary Key: 加载主键索引,DELETE标记DelVector,UPDATE执行Delete+Insert
  • MemTable 达到阈值后触发 Flush

3.3 Flush 阶段

  • MemTable 数据按排序键已有序,直接 Flush 生成 Segment 文件
  • 每个 Segment 文件包含:
    • 列式 Data Pages(压缩后)
    • Ordinal Index
    • Zone Map Index
    • Prefix Index(基于排序键)
    • Bitmap Index / Bloom Filter Index(如有)
  • 多个 Segment 文件组成一个 Rowset(对应一次导入的数据版本)

3.4 数据版本管理

  • 每次导入生成一个新 Rowset,分配递增版本号
  • Tablet 中的数据 = Base Rowset + 多个 Cumulative Rowset + 多个增量 Rowset
  • 查询时需要合并多个 Rowset 的数据
  • 版本数越多,查询性能越差(尤其是 Merge-on-Read 的 Unique Key 表)

3.5 设计取含

决策 原因
MemTable 排序写入 保证 Segment 内数据按排序键有序,利于 ZoneMap 过滤和前缀索引
批量 Flush 减少 Segment 文件数,避免小文件问题
版本化 Rowset 支持并发读写,数据一致性通过 MVCC 保证
Primary Key 的 Delete+Insert 写入时即标记删除,查询无需在线合并,3-10x 性能提升

参考: https://docs.starrocks.io/docs/table_design/table_types/primary_key_table


四、Compaction 策略(Cumulative + Base)

4.1 Compaction 概述

每次数据导入生成一个新 Rowset(数据版本文件),长期积累会产生大量小文件,降低查询效率。Compaction 负责合并多个 Rowset 为更大的文件。

4.2 Shared-nothing 模式 Compaction

Cumulative Compaction(增量合并):

  • 合并最近多个小 Rowset 为一个较大的 Cumulative Rowset
  • 不包含 Base Rowset
  • 触发条件:增量 Rowset 数量达到阈值 cumulative_compaction_num_deltas_per_compaction(默认 5)
  • 聚合模型在此阶段会进一步合并相同聚合键的数据

Base Compaction(基线合并):

  • 将 Cumulative Rowset 与 Base Rowset 合并为新的 Base Rowset
  • 聚合模型彻底合并;Merge-on-Read 模型(Unique Key)彻底合并多版本
  • 触发条件:Cumulative Rowset 数量达到阈值 base_compaction_num_cumulative_deltas(默认 5)
  • Base Compaction 开销较大,触发频率低于 Cumulative Compaction

Compaction 层级示意:

复制代码
增量 Rowset → [Cumulative Compaction] → Cumulative Rowset → [Base Compaction] → Base Rowset
  (最新小文件)                           (较大中间文件)                        (最大基线文件)

4.3 Shared-data 模式 Compaction

Shared-data 模式采用FE 控制的 Compaction 机制

  1. Score 计算: Leader FE 根据事务 Publish 结果计算并存储每个分区的 Compaction Score
  2. 候选选择: FE 选择 Max Compaction Score 最高的分区作为合并候选
  3. 任务生成: FE 发起 Compaction 事务,生成 Tablet 级子任务,分发到 CN 节点
  4. 子任务执行 : CN 后台执行,并发数由 compact_threads 控制
  5. 结果收集: FE 聚合子任务结果并提交 Compaction 事务
  6. Publish: FE 发布成功提交的 Compaction 事务

Compaction Score 规则:

  • 每个 Data File 贡献 1 分
  • Tablet 的 Rowset 按 Size 分组,文件数最多的组决定该 Tablet 的 Score
  • MaxCS < 10: Compaction 完成
  • MaxCS > 100: 不健康状态
  • MaxCS > 500: 非常高,可能需要手动干预

4.4 关键参数

参数 默认值 说明
cumulative_compaction_num_deltas_per_compaction 5 触发 Cumulative Compaction 的增量 Rowset 数
base_compaction_num_cumulative_deltas 5 触发 Base Compaction 的 Cumulative Rowset 数
compact_threads - CN 上并发 Compaction 线程数
lake_compaction_score_selector_min_score 10 FE 参数,Score 低于此值视为完成
lake_ingest_slowdown_threshold 100 FE 参数,Score 超过此值减速导入
lake_compaction_score_upper_bound 2000 FE 参数,Score 超过此值拒绝导入

4.5 设计取含

决策 原因
两级 Compaction Cumulative 轻量级频繁执行,Base 重度低频执行,平衡性能与开销
Shared-data FE 控制 数据在共享存储,FE 全局调度更高效
Score 驱动的流控 防止 Compaction 延迟过高导致查询性能严重退化
限制导入速率 避免小文件堆积超过系统处理能力

参考: https://docs.starrocks.io/docs/administration/management/compaction


五、索引类型

5.1 Prefix Index(前缀索引)

原理: 数据按排序键排序后,每 1024 行组成一个逻辑数据块,取每块第一行排序键列值构建索引条目。查询过滤条件匹配前缀索引时,可快速定位数据块。

关键限制:

  • 索引条目不能超过 36 字节
  • 只对排序键的前缀列有效(最左前缀匹配)
  • 一张表只有一个前缀索引

设计取含:

  • 36 字节限制平衡索引大小与查询效率
  • 最左前缀匹配规则,建议将高频过滤列放在排序键前面
  • v3.0+ Primary Key 和 v3.3+ 所有模型支持 ORDER BY 独立定义排序键,增加前缀索引灵活性

参考: https://docs.starrocks.io/docs/table_design/indexes

5.2 Zone Map Index

原理: 自动内置索引,存储每个 Data Chunk 的统计信息:Min、Max、HasNull、HasNotNull。查询时根据统计信息快速判断 Data Chunk 是否可跳过。

特性:

  • 内置自动索引,无需手动创建
  • 排序列效果最佳(数据有序,Min/Max 区间紧凑)
  • 非排序列效果有限(Min/Max 区间分散)
  • 仅支持范围过滤(>、<、=、BETWEEN 等)

设计取含: 自动创建、零维护成本;排序键列天然高效,非排序列效果有限是可接受的折衷

5.3 Bitmap Index

原理: 使用位数组(Bit Array),每个 bit 对应表中一行。查询时根据位图快速定位行号,支持 AND/OR 位运算。

适用场景:

  • 高基数列的等值查询(如 ID 列)
  • 多个低基数列组合查询(AND/OR)
  • 过滤效果需至少过滤 999/1000 数据行

自适应选择机制:

  • 阈值:bitmap_max_filter_ratio / 1000(默认 1)
  • 查询条件值数 / 列基数 < 阈值时使用 Bitmap Index
  • 否则自动跳过,避免加载索引开销超过收益

支持操作 : =, IN, >, >=, <, <=, IS NULL;不支持 !=, NOT LIKE

创建范围:

  • Duplicate/Primary Key 表:所有列
  • Aggregate/Unique Key 表:仅 Key 列

关键参数 : bitmap_max_filter_ratio(BE 配置,默认 1,范围 1-1000)

设计取含:

  • 不同于传统认知(Bitmap 适合低基数),StarRocks Bitmap 更适合高基数等值查询
  • 自适应选择避免误用,1000:1 过滤比是经验阈值
  • 加载 Bitmap 有 IO 开销,不适合低选择性查询

参考: https://docs.starrocks.io/docs/table_design/indexes/bitmap_index

5.4 Bloom Filter Index

原理 : 空间高效的概率数据结构,判断数据一定不存在可能存在。查询时若 Bloom Filter 判断数据文件不含目标值,直接跳过该文件。

特性:

  • 适合高基数列(如 ID 列)的 = 和 IN 查询
  • 有假阳性(误判存在),无假阴性(一定不存在)
  • 仅支持 = 和 IN 操作
  • 可通过 ALTER TABLE 动态增删

创建范围:

  • Duplicate/Primary Key 表:所有列
  • Aggregate/Unique Key 表:仅 Key 列

支持数据类型: SMALLINT, INT, BIGINT, LARGEINT, CHAR, STRING, VARCHAR, DATE, DATETIME

关键参数 : bloom_filter_columns(表属性,指定列名)

验证方法 : 查询 Profile 中 BloomFilterFilterRows 字段

设计取含:

  • Bloom Filter 空间效率极高,但仅支持等值查询
  • 假阳性可接受(最多少跳过一些文件,不漏数据)
  • 与 Prefix Index 互补:Prefix 处理排序键,Bloom Filter 处理非排序高基数列

参考: https://docs.starrocks.io/docs/table_design/indexes/bloomfilter_index

5.5 N-gram Bloom Filter Index(v3.3+, Beta)

原理 : 特殊的 Bloom Filter 索引,将字符串按 N-gram 分片后构建 Bloom Filter。加速 LIKE 查询和 ngram_search 函数。

适用场景:

  • LIKE 模糊查询加速
  • ngram_search / ngram_search_case_insensitive 函数加速

仅支持字符串类型: STRING, CHAR, VARCHAR

参考: https://docs.starrocks.io/docs/table_design/indexes/ngram_bloom_filter_index

5.6 Full-text Inverted Index(全文倒排索引)

原理: 倒排索引,快速定位包含关键词的数据行,加速全文搜索。

5.7 Vector Index(向量索引)

原理: 支持近似最近邻搜索(ANNS),用于向量检索场景。

5.8 Z-order Index

注意 : StarRocks 官方文档中未提供 Z-order Index 作为标准索引类型。Z-order 排序主要出现在部分技术博客和社区讨论中,作为多维数据排序优化的一种思路(将多维数据映射到一维以改善多维查询的局部性),但并非 StarRocks 内置索引。StarRocks 通过 Prefix Index + Bitmap Index + Bloom Filter 的组合来处理多维查询场景。

5.9 索引对比总结

索引类型 自动/手动 适用查询 适用列 过滤方式
Prefix Index 自动 前缀等值/范围 排序键前缀 快速定位 Data Chunk
Zone Map 自动 范围过滤 所有列(排序列最佳) Min/Max 跳过 Chunk
Ordinal Index 自动 行号定位 所有列 行号→物理地址
Bitmap Index 手动 高基数等值/IN/多列组合 PK/Duplicate全列,其他Key列 位图定位行号
Bloom Filter 手动 高基数等值/IN 同上 排除不含值的 Page
N-gram BF 手动 LIKE/ngram_search 字符串列 排除不含子串的 Page
Full-text 手动 全文搜索 字符串列 倒排索引
Vector 手动 ANN 搜索 向量列 近似最近邻

参考: https://docs.starrocks.io/docs/table_design/indexes


六、数据压缩

6.1 压缩算法对比

算法 压缩比 解压速度 推荐场景
LZ4(默认) 最快 通用场景,性能优先
ZSTD 较高 较快 平衡存储与性能
zlib 最高 最慢 存储空间优先
Snappy 最低 不推荐

6.2 设计取含

  • 压缩比排名:zlib > ZSTD > LZ4 > Snappy
  • 推荐 LZ4 或 ZSTD:两者在压缩比和解压性能间有良好平衡
  • 压缩算法仅建表时指定,不可修改
  • 压缩不仅节省存储空间,还减少 IO 开销(I/O 密集任务受益)
  • 代价:额外的 CPU 消耗(压缩/解压)

关键参数 : compression(表属性,建表时指定,默认 LZ4)

参考: https://docs.starrocks.io/docs/table_design/data_compression


七、磁盘数据布局

7.1 Shared-nothing 模式(BE 本地存储)

复制代码
{storage_root_path}/
├── data/
│   └── {shard_id}/
│       └── {tablet_id}/
│           ├── {schema_hash}/
│           │   ├── {rowset_id}_0.dat    # Segment 数据文件
│           │   ├── {rowset_id}_0.idx    # Segment 索引文件
│           │   ├── {rowset_id}_1.dat
│           │   ├── {rowset_id}_1.idx
│           │   └── ...
│           └── tablet_meta              # Tablet 元信息
└── ...
  • 每个 Tablet 目录下存储多个 Rowset
  • 每个 Rowset 由 .dat(数据)和 .idx(索引)文件对组成
  • Primary Key 表额外存储:主键索引文件、DelVector 文件
  • BE 支持多存储路径(SSD + HDD 混合部署)

7.2 Shared-data 模式(对象存储/HDFS)

复制代码
s3://bucket/
├── {partition_id}/
│   └── {tablet_id}/
│       ├── {rowset_id}_0.dat
│       ├── {rowset_id}_0.idx
│       └── ...
└── ...
  • 数据存储在对象存储(S3/Azure Blob/GCS/OSS)或 HDFS
  • CN 节点本地缓存热点数据(Data Cache)
  • 持久化索引可存本地磁盘(v3.1.4)或对象存储(v3.3.2, persistent_index_type = CLOUD_NATIVE)

7.3 Segment 文件内部布局

复制代码
Segment File (.dat)
┌─────────────────────────────────┐
│  Column 1 Data Pages (compressed) │
│  Column 2 Data Pages (compressed) │
│  ...                              │
│  Column N Data Pages (compressed) │
├─────────────────────────────────┤
│  Ordinal Index (per column)       │
│  Zone Map Index (per column)      │
│  Bitmap Index (optional, per col) │
│  Bloom Filter Index (optional)    │
│  Prefix Index                     │
├─────────────────────────────────┤
│  Footer                           │
│  ├── Column index offsets         │
│  ├── Segment metadata             │
│  └── Footer length + magic        │
└─────────────────────────────────┘

7.4 设计取含

决策 原因
列式 Data Page 64KB 适配压缩算法工作块大小,平衡 IO 与内存
数据与索引同文件 减少文件数,顺序 IO 读取
Shared-data 分离存储 弹性扩缩容,存储计算分离降低成本
本地 Data Cache 缓解对象存储延迟,保持查询性能

八、参考链接

  1. 数据分布(Tablet/Replica/分区/分桶): https://docs.starrocks.io/docs/table_design/data_distribution
  2. 表达式分区: https://docs.starrocks.io/docs/table_design/data_distribution/expression_partitioning
  3. 索引概览: https://docs.starrocks.io/docs/table_design/indexes
  4. Bitmap 索引: https://docs.starrocks.io/docs/table_design/indexes/bitmap_index
  5. Bloom Filter 索引: https://docs.starrocks.io/docs/table_design/indexes/bloomfilter_index
  6. 数据压缩: https://docs.starrocks.io/docs/table_design/data_compression
  7. Compaction 管理: https://docs.starrocks.io/docs/administration/management/compaction
  8. Primary Key 表: https://docs.starrocks.io/docs/table_design/table_types/primary_key_table
  9. 架构概览: https://docs.starrocks.io/docs/introduction/Architecture
  10. GitHub 源码: https://github.com/StarRocks/starrocks
相关推荐
云登指纹浏览器13 小时前
2026静态IP和动态IP怎么选?跨境电商场景应用完整指南
大数据·网络协议·tcp/ip
vx1530278236213 小时前
CDGA|企业数据治理中,AI权限该如何拿捏分寸
大数据·人工智能·cdga·数据治理
事变天下14 小时前
奥哲重构电建新范式!AI赋能电力建设全场景智能化升级
大数据·人工智能
Lalolander14 小时前
设备工程项目如何高效管理项目进度与成本?
大数据·运维·设备工程项目管理·设备工程项目成本管理·工程项目进度管理
许彰午14 小时前
零跑腿服务的三条核心流程
大数据
多年小白14 小时前
英伟达VR200机柜PCB价值量同比+233%:AI硬件主线如何被引爆?
大数据·人工智能·科技·深度学习·ai
Daorigin_com14 小时前
从“被动领罚”到“主动合规”:强监管时代下,道本科技用数字化为企业筑牢“合规生命线”
大数据·数据仓库·科技·流程图·软件构建·数据库开发·数据库架构
一个数据大开发15 小时前
大模型驱动下的数据中台架构演进:从服务化到智能化
大数据·数据仓库·vscode·pycharm
金融小师妹15 小时前
基于AI联储治理模型的政策重构分析:沃什试图重塑美联储,但现实复杂度远超预期
大数据·深度学习·逻辑回归·线性回归