StarRocks 的实时更新
实时更新需求
实时更新需求主要体现在数据库 ELT 和传统 OLAP 系统中,传统方式存在 T+1 批 ETL 延迟高、仅增量追加无更新、读取时追加更新合并查询性能差等问题,难以满足实时数据、热数据、易失性数据以及 TP 到 AP 同步管道的需求。常见用例包括全行 upsert/delete,其中全行向上插入(或删除)是最常见的形式,适用于 MySQL 和 StarRocks 等系统。StarRocks 支持唯一键加载(upsert)和主键加载(upsert/delete),满足 TP 到 AP CDC 同步需求。
StarRocks 的实时更新
系统概述
StarRocks 的实时更新系统通过多个平板电脑(tablet)协同工作,实现高效的写入和更新操作。写入流程包括写入、使用版本提交、接收数据/排序、合并、分裂、刷新 MemTable 等步骤。元数据存储在 RocksDB 中,包括版本信息、行集、增量等,并通过内存缓存提高访问效率。
元数据管理
元数据包括版本信息(major、minor)、行集(Rowset)和增量(Delta),存储在 RocksDB 中并缓存在内存中。版本信息记录了每次提交的版本号和对应的行集及增量,通过 rowset_id_next 指针进行管理。
写入流程示例
以写入操作为例,展示了版本提交、行集合并、压实等过程,以及元数据更新和主索引操作。写入过程中,数据首先写入 MemTable,然后进行排序、合并、分裂和刷新,最终提交到 RocksDB。主索引更新是关键步骤,通过复合主键编码二进制切片,快速定位行位置,实现高效的更新操作。
并发控制
并发控制通过每个只写 TXN 有两个阶段(FE 提交版本和写入)实现。主索引更新在提交阶段需要 >90% 的时间,主要通过高效的内存中 hashmap 实现,每个存储桶更新 1M op,提交持续时间约为 0.12s(假设 10M op/s)。一级指标优化包括大型 hashmap 缓存缺失问题,通过批量更新预取和内存使用优化解决。永久主索引通过磁盘 hashmap 和 L0/L1 类 LSM 结构实现。
使用案例
使用案例包括冷/热数据管理,通过按日期划分数据分区,只有最近的分区有更新,从而降低负载指数。宽表用例中,大列主键只占用总存储空间的一小部分,如用户配置文件使用 user_id 作为主键。
压实
压实过程包括合并小文件和真空删除,但需要维护一级索引,并读取和跳过删除的行,从而减慢扫描速度。LSM 压实通过合并 sst 生成新的 sst 并原子替换元数据实现。
基准测试
基准测试包括单个表上的简单查询和 TPC-H 1T 数据集,展示了 StarRocks 在实时更新场景下的性能表现。
当前和未来工作
读写更新
读写更新包括部分更新、条件更新和合并更新。部分更新通过在流系统中加入、TP 中更新后 CDC 到 AP 或批处理“合并到”等方式实现。条件更新通过无序到达更新(ts > old.ts)和使用 dest.id = src.id 合并到 dest 实现。合并更新通过 dest.id = src.id 合并到 dest 并进行数组追加或映射/集合添加实现。
一般读写事务
一般读写事务包括删除、插入、合并和多语句事务,如数据修复(批量删除 + 更新)。交易难度级别根据读/写集关系进行分类,其中一般读写事务优化机会较多。
实体化视图
实体化视图通过主表和物化视图实现,如订单表和收入按城市分区统计的物化视图。