StarRocks 存算分离架构下的大规模实时导入优化实践

作者:王衍波, StarRocks TSC Member;镜舟科技高级研发工程师

导读:存算分离架构能够显著降低存储成本并提升系统弹性,但随着实时数据规模不断增长,对象存储请求、小文件、Compaction 以及 Publish 等环节逐渐成为大规模实时导入的性能瓶颈。针对这些挑战,StarRocks 围绕文件合并、大 Tablet、Tablet 内并行和主键索引优化等关键技术进行了系统性优化,并在多个生产场景中取得了显著效果。本文整理自王衍波在 Flink Forward Asia 2026 的分享,将介绍这些优化的设计思路、实现方式及实践案例。

存算分离架构下实时导入面临的挑战

在存算分离架构中,数据统一存储在 Amazon S3 或兼容 S3 协议的对象存储中,计算节点(CN)仅负责计算和缓存。相比存算一体架构,存算分离能够降低存储和运维成本,支持计算节点秒级弹性扩缩容,并通过 Warehouse 实现导入、查询、Compaction 等不同负载的资源隔离。

不过,存算分离的实时导入能力也受到对象存储特性的影响。对象存储读写延迟相对较高,并按照请求次数计费,因此在高频实时写入场景下,如何降低对象存储请求数量、减少导入延迟,成为存算分离架构需要重点解决的问题。

实时导入流程

在实际生产环境中,实时数据通常来自三类数据源:

  • Flink(包括 Flink CDC),通过 Flink Connector 导入 StarRocks;

  • Kafka,通过 Routine Load 持续消费数据;

  • 本地文件,通过 Stream Load 导入。

数据进入 StarRocks 后,首先发送到协调 CN 节点,由协调节点按照分区和分桶规则将数据路由到对应的 Tablet。各 Tablet 先将数据写入内存,当达到刷盘阈值后,再写入对象存储生成数据文件,并记录 Txn Log。最后,由 FE 完成 Publish Version,更新 Tablet Meta,整个事务提交完成。

对于 Primary Key 表,在 Publish Version 阶段还需要读取并更新主键索引,因此相比明细模型会带来更高的处理开销。同时,同一 Tablet 的多个版本需要串行完成 Publish Version,当实时导入频率较高时,该阶段容易成为整个导入链路的性能瓶颈。

存算分离大规模实时导入的三重挑战

结合导入流程,可以将存算分离架构下实时导入面临的问题归纳为三点:

  • 小文件数量过多。 每次导入都会生成大量小文件,如果 Compaction 不够及时,会影响后续查询性能。

  • 对象存储请求成本较高。 对象存储写请求数量与 Tablet 数量直接相关。当一次导入涉及 N 个 Tablet 时,整个导入流程需要向对象存储发起约 3N 次写请求。在高频实时写入场景下,大量请求不仅增加存储成本,也会影响整体导入效率。

  • 对象存储访问延迟较高。 单次读写通常需要几十毫秒甚至数百毫秒。当某个 Tablet 因数据倾斜等原因处理速度较慢时,整个事务都需要等待其完成,从而影响实时导入吞吐。

核心优化

文件合并 File Bundling

针对前面提到的小文件数量多、对象存储请求成本高等问题,StarRocks 在存算分离架构下进行了多项优化,包括文件合并(File Bundling)、大 Tablet 支持以及围绕大 Tablet 的并行优化。其中,文件合并的目标是减少对象存储的小文件数量以及读写请求次数,从而降低存储成本并提升导入效率。

在优化前,一次导入过程中,每个 Tablet 都会分别生成数据文件、Txn Log 和 Tablet Meta,因此对象存储写请求数量与 Tablet 数量成正比。假设一次导入涉及 N 个 Tablet,则需要向对象存储发起约 3N 次写请求。

为减少小文件数量,StarRocks 对同一次导入生成的文件进行了合并:

  • Tablet Meta:同一 Partition 下所有 Tablet 的元数据统一合并为一个文件;

  • Txn Log:同样合并为一个文件;

  • 数据文件:在 CN 节点内部完成合并,每个 CN 最终仅生成一个数据文件。

因此,对于一个 Partition,最终生成的文件数量由原来的 3N 个降低为 2 + M 个,其中 M 为参与导入的 CN 节点数量。

例如,一个 Partition 包含 10 个 Tablet ,由 3 个 CN 共同完成导入:

  • 优化前 :需要生成约 30 个文件(3 × 10);

  • 优化后 :仅生成 5 个文件(2 + 3)。

对象存储写请求次数由 30 次 降低至 5 次,显著减少了对象存储 API 调用次数。后文将结合实际案例进一步展示该优化带来的效果。

大Tablet:单 tablet 容量 1GB → 100GB

除了文件合并之外,StarRocks 还在存算分离架构下支持了更大的 Tablet,将单个 Tablet 的推荐容量从传统的 1~10 GB 提升至 最高 100 GB

在存算一体架构中,小 Tablet 有其优势。一方面,StarRocks 内部许多任务以 Tablet 为并行单位,Tablet 数量越多,并行度越高;另一方面,由于存算一体需要维护本地多副本,小 Tablet 在副本均衡和副本修复过程中效率更高,因此长期以来推荐将 Tablet 控制在 1~10 GB 左右。

但在存算分离架构下,小 Tablet 带来的收益已经不再明显,反而会引入额外开销。

  • 每个 Tablet 都需要独立维护导入状态,包括 MemTable、Primary Key 索引等结构。当 Tablet 数量持续增加时,这些元数据和内存资源会不断累积,带来更高的资源消耗。

  • 大量 Tablet 还会增加 FE 的元数据管理压力,进一步影响系统整体效率。

由于存算分离架构的数据统一存储在对象存储中,不再需要像存算一体架构那样进行本地副本修复和数据迁移,因此可以支持更大的 Tablet 容量,最高可达 100 GB

采用大 Tablet 后,系统能够显著减少 Tablet 数量,相应地,MemTable、Primary Key 索引等导入状态的维护数量也随之减少,从而有效降低内存和元数据开销,为大规模实时导入提供更好的资源利用效率。

StarRocks 原有的许多操作以 Tablet 为并行粒度。随着单个 Tablet 容量增大,仅依赖 Tablet 之间的并行已经难以充分发挥系统性能,因此还需要配套 Tablet 内部的并行优化。

相关优化主要包括三个方面:

  • 导入写入阶段的并行优化;

  • Tablet 内 Compaction 的并行优化;

  • Primary Key 表及主键索引相关优化。

导入写并行

优化前,Delta Writer 线程不仅负责向 MemTable 写入数据,还需要在 MemTable 交付前执行 Finalize,包括排序和聚合等操作。由于 Finalize 会持续占用写线程,在此期间新的数据无法继续写入。

完成 Finalize 后,MemTable 才会进入 memtable_flush 线程。为保证数据顺序,同一个 Tablet 内的多个 MemTable 采用串行方式 Flush,写入与刷盘过程无法充分重叠,因而限制了单个 Tablet 的导入吞吐。

针对这一问题,StarRocks 对导入链路进行了两项优化:

  1. MemTable Finalize 并行化: 将 Finalize 从 Delta Writer 写线程中移出,交由 memtable_flush 线程池执行。Delta Writer 完成 MemTable 写入后即可立即交付,不再等待排序和聚合完成,从而避免后续写入被阻塞。

  2. MemTable 并行 Flush: 将同一个 Tablet 内 MemTable 的 Flush 模式由串行调整为并行,并通过 slot_idx 保证处理顺序。这样,不同 MemTable 的 Finalize 和 Flush 可以在同一线程池中并发执行。

经过上述调整,CPU 密集型的 Finalize 与 I/O 密集型的 Flush 可以重叠执行,同时写线程不再被串行刷盘过程阻塞,从而显著提升单个 Tablet 的导入吞吐。

Compaction 并行

优化前,单个 Tablet 的 Compaction 任务只能由一个线程执行,数据读取、合并和写回均采用串行方式。对于大 Tablet,尤其是在执行 Base Compaction、需要与基线数据进行合并时,涉及的读写数据量较大,整体执行耗时也会明显增加。

针对这一问题,StarRocks 对 Tablet 内部的 Compaction 流程进行了并行化改造,主要包括三种方式:

  • Rowset 分组并行:将参与 Compaction 的 Rowset 划分为不同分组,各组之间可以并行处理;

  • Segment 分组并行:当单个 Rowset 较大时,进一步按 Segment 进行分组,在更细粒度上并行执行;

  • Key Range 并行:按照 Key Range 对 Rowset 或 Segment 中的数据进行划分,不同 Range 之间并行完成数据合并。

通过将 Compaction 从单线程串行处理扩展为 Rowset、Segment 和 Key Range 等多个粒度的并行处理,可以提升大 Tablet 场景下的 Compaction 效率,缩短数据合并时间。

主键索引优化

第三类 Tablet 内并行优化主要面向 Primary Key 表和主键索引,重点解决 Publish Version 阶段的性能问题。

主键索引结构

在介绍主键索引相关优化之前,先简单回顾一下 StarRocks 主键索引(Primary Key Index)的基本结构。

主键索引的主要作用是维护主键与数据位置之间的映射关系。当写入一条数据时,系统首先根据主键查询索引,判断该记录是否已存在:如果存在,则更新对应记录;如果不存在,则新增一条记录。对于 Delete 操作,同样需要通过主键索引定位数据所在的 Rowset、Segment 及对应行号,再完成删除标记。

逻辑上,主键索引可以看作一个有序的 Key-Value 结构。其中,Key 为编码后的主键,Value 用于记录数据所在的 Rowset、Segment 及对应行号。查询时,通过二分查找即可快速定位目标记录。

物理存储方面,StarRocks 基于 LSM Tree 组织主键索引。新写入的数据首先缓存在 MemTable 中,当 MemTable 达到阈值后,会 Flush 生成 SSTable。在存算分离架构下,这些 SSTable 存储于对象存储中,并由后台持续执行 Compaction,将多个小 SSTable 合并为更大的 SSTable,以降低后续查询和更新的开销。

主键索引优化(一):生成前移到 data write 阶段

基于上述主键索引结构,StarRocks 针对大规模导入、Compaction 以及数据倾斜等场景,对主键索引进行了多项优化。第一项优化是将 SSTable 的生成从 Publish 阶段前移到数据写入阶段

优化前,数据首先写入 Segment,随后由 FE 调度进入 Publish 阶段,在 Publish 过程中生成 SSTable 并更新主键索引。当导入数据量较大时,生成 SSTable 的开销较高,会显著拉长 Publish 时间。

此外,同一 Tablet 上多个事务的 Publish 操作需要串行执行,因此一旦某个事务在生成 SSTable 时耗时较长,后续事务也需要依次等待,容易成为整个导入链路的性能瓶颈。

针对这一问题,StarRocks 将 SSTable 的生成提前至数据写入阶段,与 Segment 写入同步完成。由于数据写入阶段本身支持并行执行,因此 SSTable 的构建也可以并行完成。

这样一来,Publish 阶段无需再生成 SSTable,只需将已生成的 SSTable 注册到主键索引中即可,大幅降低了 Publish 阶段的执行开销,同时减少了串行等待时间。

主键索引优化(二):索引 Compaction 优化

主键索引采用 LSM Tree 结构,新写入的数据会不断生成新的 SSTable,因此后台需要持续执行 Compaction,将多个小 SSTable 合并为更大的 SSTable。

在大 Tablet 场景下,随着数据持续写入,Base SST 会越来越大。优化前,Base Compaction 采用单线程执行,需要重写整个 Base SST,无法并行处理,因此耗时较长,也容易产生较高的写放大。

针对这一问题,StarRocks 对索引 Compaction 进行了优化,引入 Sorted Fileset 组织方式。

优化后,系统首先按照 size-tiered 策略选择需要参与 Compaction 的 SSTable,再根据 Key Range 将其划分为多个互不重叠的 Sorted Fileset。每个 Fileset 可以独立执行 Compaction,并行生成新的 SSTable,最终完成整个索引 Compaction 过程。

相比优化前只能对单个 Base SST 串行重写,新的方案能够充分利用多核资源,实现多个 Fileset 并行 Compaction,从而显著提升大 Tablet 场景下主键索引的 Compaction 效率。

主键索引优化(三) :Tablet 内 Publish 并行

经过前两项优化后,SSTable 的生成已经前移至数据写入阶段,但 Publish 仍然以 Tablet 为粒度串行执行,其主要耗时集中在主键索引查询(Index Lookup)、SST 打开以及 Delete 文件读取等操作。

针对这一问题,StarRocks 对 Publish 阶段进行了进一步并行化改造。

优化前,Publish 按 Chunk 顺序执行:每读取一个 Chunk,依次完成主键索引查询、主键索引更新以及 Delete Vector 更新,然后再处理下一个 Chunk,整个过程采用串行方式执行。

优化后,系统将数据按 Chunk 划分为多个并行任务,每个任务独立完成主键索引查询(Index Lookup)、主键更新等操作,从而实现 Publish 阶段的并行执行。

除主键索引查询外,SST 打开和 Delete 文件读取也进行了并行优化。其中,主键索引按照 Scan Range 切分为多个 Chunk,由多个线程同时执行 Lookup 和 Upsert;SST 打开通过独立线程池并行完成,Delete 文件读取也采用并行执行方式,进一步降低了 Publish 阶段的整体耗时。

通过上述三项优化,主键索引在 Publish 阶段的主要性能瓶颈得到有效缓解,大幅缩短了主键表实时导入的 Publish 耗时。

案例分享

案例一:聚水潭

聚水潭是一家电商 SaaS ERP 服务商,为数十万商家提供报表分析服务,其业务场景涉及 Flink 百亿级数据实时写入。

在存算分离架构下,随着持续写入,Compaction 难以及时完成,Compaction Score 持续升高,实时写入吞吐受到限制。同时,大量小文件也导致对象存储写请求频繁,进一步增加了写放大和存储成本。

针对上述问题,聚水潭启用了文件合并(Merge Commit)等优化能力。

优化后,对象存储写请求数量显著下降。从监控数据来看,S3 写请求数由约 300 次 降低至约 50 次

案例二:腾讯音乐

腾讯音乐的业务场景具有高并发、大数据量的特点。实时数据通过 Kafka 导入 StarRocks,共运行 24 个 Routine Load Job,每个 Job 包含 5 个 Task,每 10 秒触发一次导入,每小时写入数据量约 1 TB。

在启用文件合并(Merge Commit)优化后,对象存储写请求显著减少。从监控数据来看,S3 写请求由每秒约 100~150 次 降低至约 8 次,有效减少了对象存储 API 调用次数,在高并发实时写入场景下进一步降低了存储成本。

案例三:某实时记账平台

某实时记账平台对实时导入延迟有着严格要求,SLA 规定 P99(Max)≤ 5 秒P90 ≤ 3 秒

与常见的实时写入场景不同,该业务不仅写入最新分区,还会频繁回填历史数据、执行历史更正和离线重算,因此一次事务往往会涉及数千万历史分区和上万个 Tablet,对实时导入性能提出了更高要求。

在 StarRocks v4.0 中,虽然已经引入了文件合并等优化,但由于单次事务涉及 Tablet 数量过多,Compaction、Publish 以及主键索引 SST 构建等操作仍容易成为性能瓶颈,导入延迟最高超过 30 秒,无法满足业务 SLA。

在 StarRocks v4.1 中,通过引入大 Tablet、混合主键索引(Compaction 期间生成 SST,减少 Publish 开销)以及 Tablet 内 Publish 并行等优化,实时导入 P99(Max)成功降至 5 秒以内,满足了业务对实时导入延迟的要求。

未来规划

未来,StarRocks 将继续围绕存算分离架构下的大规模实时导入能力进行优化,重点包括以下两个方向:

  • Range 分布(Range Distribution)支持。 当前 Hash 分布在部分数据倾斜场景下存在一定局限,未来将支持 Range 分布,以进一步提升数据倾斜场景下的数据分布和导入性能。该功能已完成大部分开发工作,计划在后续版本中发布。

  • 持续优化大 Tablet 能力。 在现有基础上继续支持更大容量的 Tablet,并进一步完善全链路并行化能力,持续提升大规模实时导入场景下的性能表现。

相关推荐
李兆龙的博客33 分钟前
问津集 #15:RangeReduce——查询驱动 Compaction 收益
compaction
StarRocks_labs1 天前
基于 Fluss、Paimon 与 StarRocks 构建淘天集团湖流一体数据链路
starrocks·olap·schema·paimon·fluss·湖流一体
ZCBUS实时计算2 天前
信创混合存储架构落地实战|基于 ZCBUS 实时计算构建证券高可用实时风控数仓
大数据·架构·flink·kafka·dba
效率工作实验室2 天前
实时数据分析平台有哪些?流式分析引擎对比
flink·实时数据分析平台·流式分析引擎·流处理引擎对比·实时olap数据库
数智启示录2 天前
Flink CDC 机制精讲(四):一条 SQLServer CDC 事件如何保持顺序 【面试宝典】
数据库·面试·sqlserver·flink
StarRocks_labs2 天前
从 6000+ Commit 中识别升级风险:一个 StarRocks AI 升级扫描工具的实现
starrocks·ai·commit·分析·claude code
数智启示录2 天前
Flink CDC 机制精讲(五):Operator UID、Savepoint 与安全升级 【面试宝典】
大数据·面试·flink
数智启示录2 天前
Flink CDC 机制精讲(七):用故障注入证明链路是否可靠 【面试宝典】
大数据·经验分享·面试·flink
StarRocks_labs2 天前
StarRocks 4.1:聚焦生产实践,持续降低运维复杂度
运维·starrocks·iceberg·schema·物化视图·tablet·存算分离架构