把一份在线交易(OLTP)刚写下的订单,在下一秒就纳入全公司的实时报表(OLAP),这是企业数据平台近十年反复讨论的问题。传统架构是两条管线:OLTP 系统处理写入与点查,通过 CDC(Change Data Capture)把变更异步送到 OLAP 仓库;两边各自为政,报表通常滞后分钟级到小时级。HTAP(Hybrid Transactional/Analytical Processing)的目标是把这两段路径合而为一:同一份数据,既能低延迟更新,也能高吞吐扫描。
这件事之所以难,根本原因在于 OLTP 与 OLAP 对存储布局、索引结构、并发控制的要求几乎相反。OLTP 偏好行存、B+ 树索引、MVCC 加行锁、写放大低;OLAP 偏好列存、字典与游程压缩、向量化扫描、批量读取。把两套系统放在一个引擎里,任何一边都要妥协。过去十年,学术界与工业界给出的答案可以粗略归为三类:行列双引擎(TiDB + TiFlash、F1 Lightning)、行列一体存储(SingleStore Universal Storage、SAP HANA、OceanBase),以及”把 OLTP 留在外面,让 OLAP 存储直接承担可更新性”的 Lakehouse 路线(Delta Lake、Iceberg、Hudi)。
本文上半部分梳理这四条路线的论文与核心机制:它们如何做工作负载隔离(Workload Isolation),如何定义分析视图对事务视图的新鲜度(Freshness)边界,以及在一致性/可用性/性能三角里各自站在哪里。下半部分讨论怎么测一个 HTAP 系统——HATtrick 与 CH-benCHmark 的假设是什么、有什么盲点——以及在”我到底需不需要 HTAP”这个问题上的选型决策。
版本说明 本文引用的版本:TiDB 7.x / TiFlash 7.x,SingleStore 8.x,Databricks Delta Lake 3.x,Apache Iceberg 1.4.x,Apache Hudi 0.14.x。涉及版本差异处会单独标注。
一、HTAP 的问题定义与工作负载隔离
1.1 为什么”一份数据两套负载”这么难
数据库里”一份数据”的含义至少有两层:逻辑层面,应用看到的是同一张表;物理层面,实际可能有多份拷贝,分布在不同的节点、不同的存储格式上。HTAP 系统的工程取舍,本质上就是在这两层之间做映射。
OLTP 工作负载的典型特征:小事务、写频繁、点查和短范围扫描为主、延迟要求在毫秒级、并发度几千到几万。行存(Row Store)在这种场景下最划算——一行记录的所有列在物理上相邻,读一行就是一次 I/O;B+ 树索引按主键排列,点查是 O(log n) 的路径。MVCC(Multi-Version Concurrency Control)给每次写入生成新版本,读写互不阻塞,但也意味着同一条记录可能有多个版本共存。
OLAP 工作负载的典型特征:大表全扫、少量列投影、聚合与窗口函数、latency 容忍秒级到分钟级、并发度几十到几百。列存(Column Store)把同一列的值聚在一起,单列扫描的 I/O 放大很低,字典编码、游程编码、位图索引能把存储体积压到行存的 1/5 到 1/20(参见本仓库《列式存储原理》与《压缩算法工程实践》)。向量化执行(Vectorized Execution)每次处理一批值,CPU 流水线与 SIMD 指令效率高。
把这两种负载同时压到一个存储引擎上,常见的坏结果有三种:
- 缓存互相污染。分析查询一次扫过去几百 GB,把 OLTP 需要的热点页全部挤出 buffer pool,点查延迟开始抖动。
- 锁与 MVCC 版本链爆炸。一个长跑的分析事务会让 undo 链无法回收,行存表变得越来越胖,点查也被拖累。
- 压缩与索引的两难。OLTP 需要行内更新代价低,不能过度编码;OLAP 需要字典编码和游程编码,每次更新都要重写整个列块。
所有 HTAP 系统都要回答的第一个问题是:工作负载隔离(Workload Isolation)做到哪一层? 是共享同一份数据但在 CPU/内存/IO 层面分流(软隔离),还是物理上复制出第二份面向 OLAP 的副本(硬隔离),或者介于两者之间。
1.2 新鲜度边界:从 “秒级” 到 “读己之写”
HTAP 的第二个核心概念是新鲜度(Freshness):分析侧能看到多新的事务数据?定义这一点需要两个参数:
- 可见时延(Visibility Lag):事务提交后,多久之后分析查询能读到;
- 一致性级别:分析查询读到的那个”快照”,相对事务侧是否满足某种一致性(快照一致性、线性一致性、read-your-writes 等)。
常见的三档:
| 档位 | 可见时延 | 一致性 | 典型实现 |
|---|---|---|---|
| CDC 型 | 秒级到分钟级 | 最终一致 | F1 Lightning、传统数仓管线 |
| 准实时 | 亚秒级 | 快照一致(基于 Raft/Paxos 日志同步) | TiDB + TiFlash |
| 完全实时 | 事务提交即可见 | 强一致(同一存储,同一事务) | SingleStore Universal Storage、HANA |
档位越靠下,工程复杂度越高,因为要在写入路径上同步维护行列两份表示。档位越靠上,复杂度越低但业务上要接受”分析结果永远比交易滞后若干秒”。
HTAP 系统的论文和文档里”实时”一词的含义经常不一致。在 TiFlash 的语境下,“实时”是指通过 Raft Learner 同步日志到列存副本、并以事务快照读保证一致性;在 SingleStore 的语境下,“实时”是指同一个存储引擎同时承担行列表示、事务提交即对分析可见。读论文时第一件事是先定位新鲜度档位,再看机制。
1.3 评估 HTAP 系统的坐标系
综合前两小节,可以提出一个四维坐标系来评价任何 HTAP 系统:
- 隔离方式:物理副本 / 同一存储双格式 / 完全共享;
- 新鲜度档位:CDC / 准实时 / 完全实时;
- 事务一致性:快照一致 / 可串行化 / 外部一致(Spanner 式);
- 弹性扩展:行列两侧能否独立扩缩容。
本文后续章节会用这四个坐标刻画每个具体系统。
1.4 一个容易忽略的维度:schema 变更
讨论 HTAP 时容易只看”读写分流”,忽略 schema 变更。真实系统里,加列、改类型、加索引每天都在发生,行列双维护对这类操作极不友好:
- 在一个行存副本上加列是 DDL online 的事;
- 在列存副本上加列要重写该列的所有 Segment / Layer;
- 两侧 schema 暂时不一致时,查询路由需要保证不会读到错列。
TiFlash、SingleStore、HANA 都为 online DDL 做了专门设计,但边角场景(改主键、改分区键、改字符集)仍然是踩坑重灾区。评估 HTAP 系统时,把 DDL 支持度单列一个维度,可以识别大量营销话术掩盖下的工程短板。
二、TiDB + TiFlash:基于 Raft Learner 的行列分流
2.1 架构
TiDB 的 HTAP 能力来自 TiFlash 列存副本。Huang 等人在 VLDB 2020 的论文 “TiDB: A Raft-based HTAP Database” 里把它的关键点讲清楚了:
- TiDB 的底层是 TiKV,一个基于 Raft 的分布式行存,按 Region 分片,每个 Region 默认 3 副本。
- TiFlash 是一个可插入任意 Region 的 Raft Learner(学习者副本),只接收日志、不参与选主。
- TiFlash 收到 Raft 日志后,解码行存变更并重放到列存格式(DeltaTree,简化版 LSM 思想,行存 Delta 层 + 列存 Stable 层)。
- 查询时,TiDB 的查询优化器根据代价模型决定单张表读 TiKV 还是 TiFlash,甚至可以在一个查询里混合用两边。
这个架构的关键之处在于:复用 Raft 作为同步通道。Raft 日志天然带全序与 commit index,TiFlash 拉取日志的同时就拿到了一致性读的锚点——只要读取点 Ts 小于 TiFlash 已经 apply 的日志位点所对应的事务提交时间,该读取就是一致的。
2.2 一致性读与 safe-ts
TiDB 的事务采用 Percolator 风格(参见《Percolator 与分布式事务》),提交时从 PD(Placement Driver)获取全局时间戳(TSO)。TiFlash 的快照读有一个 “safe-ts” 概念:对于某个 Region,safe-ts 是一个时间戳 T,保证所有 commit_ts ≤ T 的事务已经在该副本上 apply 完毕。
查询到达 TiFlash 时,如果读取时间戳 Ts ≤ safe-ts,直接读;否则等待 safe-ts 推进到 Ts 或者回退到 TiKV。工程上 safe-ts 由两部分构成:Raft apply 位点对应的最大 commit_ts,以及对未决事务(有 prewrite 但没 commit 的)做 resolve。这一机制让列存侧在不走两阶段提交、不修改 TiKV 写入路径的前提下拿到了快照一致性。
2.3 代价模型与路由
TiFlash 不是总是更快。单行点查、按主键的小范围扫描,TiKV 比 TiFlash 快一个数量级(列存要拼列、要解压)。因此 TiDB 优化器需要一个代价模型来选择副本。
论文里给的简化模型(文字版):
- 对每张参与表估计扫描行数 N 与投影列数 k;
- TiKV 代价 ≈ N × 全列宽度;
- TiFlash 代价 ≈ N × (k / 全列数) × 压缩后列宽 + 解压开销;
- 再加上向量化执行带来的常数因子差异。
实际工程里还要考虑并发度、索引覆盖情况、是否能下推聚合到
TiFlash(TiFlash MPP
模式允许多机并行聚合再汇总)。优化器选错时可以用 hint(如
/*+ READ_FROM_STORAGE(TIFLASH[t]) */)强制。
2.4 MPP 下推与向量化
TiFlash 从 6.x 开始引入 MPP(Massively Parallel Processing)模式:分析查询可以在多个 TiFlash 节点之间做 shuffle、hash join、聚合下推。对比传统的”单节点扫完拼起来”,MPP 能让大 join / 大 group by 线性扩展。
实际调度里,优化器会根据统计信息估计”这个查询值不值得走 MPP”:
- 单表简单扫描、结果行数小:不走 MPP,减少 shuffle 开销;
- 多表 join、join 键分布均匀:走 MPP,每节点 hash 分片后并行;
- 数据倾斜严重:MPP 反而可能比单点慢,因为最慢的分区拖垮整体。
TiFlash 的向量化执行引擎在 v7.x 之后基于 ClickHouse 的执行核心进一步重写,列式 batch、SIMD、表达式 JIT 都能带来明显加速。这是 “行列双维护” 路线里容易被忽略的一点:列存副本不只是存得紧,执行层也要彻底换代,否则白送一半收益。
2.5 隔离强度与弹性
回到坐标系:
- 隔离方式:物理副本。TiFlash 副本独立部署,CPU、内存、磁盘与 TiKV 完全分开。
- 新鲜度档位:准实时。Raft Learner 日志同步,正常情况亚秒级。
- 事务一致性:快照一致。对 TiFlash 的读,等同于对 TiKV 某个 Ts 的快照读。
- 弹性扩展:行列两侧独立扩缩容,TiFlash 副本数量可按表级别配置。
踩坑点:
- TiFlash Learner 同步跟不上时,safe-ts 推进变慢,分析查询要么等要么退回 TiKV。大事务(百万行以上)会显著放大这个问题。
- DDL 变更要在 TiKV / TiFlash 两侧协调。加列、改类型的语义要在列存 Delta 合并时正确处理。
- TiFlash 的 DeltaTree 在 Delta 层积累过多时点查退化,Stable 层 compaction 又会消耗大量 I/O。Compaction 策略需要按业务实际压力调。
三、SingleStore Universal Storage:同一引擎里的行列一体
3.1 从行存 + 列存两张表到一份表
SingleStore(原名 MemSQL)最早的设计是把行存表和列存表分开:内存行存(Rowstore)吃 OLTP,磁盘列存(Columnstore)吃 OLAP,应用自己选。Universal Storage 是他们在 7.0 之后推出的统一存储格式,核心想法是:
- 底层存储是列式的段(Segment),每段若干万到百万行;
- 每段带一个行级的 “隐藏行存” 区域(内部叫 in-memory row segment 或 seekable row segment),承接最近的更新;
- 段满或达到阈值后,冻结成只读列段并写入磁盘;
- 支持二级索引(Secondary Index)和唯一约束,这是和传统列存引擎最大的差别。
这让一张表在同一份存储里同时具备:列扫描的吞吐、点查的延迟、事务更新的 ACID。代价是每次写入要同时维护多个索引和列段元数据,写放大比纯行存高。
3.2 写入路径
写入一条新行,SingleStore Universal Storage 的大致流程:
- 写入 WAL;
- 写入活跃行段(row segment)——这是一个内存结构,可看作小的 B+ 树或哈希表;
- 更新涉及到的二级索引;
- 行段积累到阈值后,后台任务把它”冻结”为只读的列段(Sorted Run),应用列式编码与压缩;
- 列段持续 compaction,合并小段、重建索引统计。
更新一条已存在的行则更复杂:如果这行还在活跃行段,原地更新;如果已经进入冻结的列段,标记删除 + 在行段里插入新版本,后续 compaction 再物化。这种 “追加式更新” 对 OLTP 友好,但要求元数据层能快速判断一行的当前有效版本在哪里。
3.3 坐标系定位
- 隔离方式:同一存储双格式。没有物理副本,行列共享存储。
- 新鲜度档位:完全实时。事务一提交,分析查询就能看到。
- 事务一致性:可串行化(通过 2PL + MVCC 组合)。
- 弹性扩展:单点容量有限,跨节点扩展靠分片,不像 TiDB 那样有独立列存层。
代价:单节点在高并发 OLTP 下,同时承担列段 compaction、索引维护、分析扫描,容易出现资源抢占;大分析查询可以通过资源池(Resource Pool)隔离,但本质上还是共享 CPU 与内存。
Universal Storage 的工程价值在于”简化运维”:用户看到的是一张普通 SQL 表,不需要关心行列副本、不需要配同步链路。代价是规模上限与超大分析查询的隔离不如 TiDB 硬副本方案。
四、F1 Lightning:CDC-to-Columnar 的另一种解法
4.1 为什么 Google 不直接改 F1
Yang 等人在 VLDB 2020 的论文 “F1 Lightning: HTAP as a Service” 给出了 Google 内部的 HTAP 方案。背景是 F1 已经是一个跑在 Spanner 上的大规模事务系统,改 F1 和 Spanner 的存储层代价巨大。于是他们选择了”外挂”路线:
- Lightning 是一个独立的列存系统,不修改 F1/Spanner;
- 通过 changepump(一个订阅 Spanner 变更流的服务)把事务日志变换为列式增量;
- 列式增量在 Lightning 里合并成列段,提供分析查询接口;
- 查询引擎(F1 Query)对同一个逻辑表既能下推到 Spanner 也能下推到 Lightning。
这本质上是把 CDC 管线做成”原生服务”,但在几个关键点上比普通 CDC 强:
- changepump 保证事件按事务边界、按分区顺序投递,不会出现部分事务可见;
- Lightning 维护每个表的安全时间戳(safe timestamp),查询时以此判断数据是否足够新;
- Lightning 的列存格式允许合并删除与更新,而不是像传统 CDC + Parquet 那样只能追加。
4.2 新鲜度与隔离
- 隔离方式:独立系统 + CDC 同步。Spanner 与 Lightning 物理完全分离。
- 新鲜度档位:准实时(秒级)。论文给出的典型 lag 在 5–10 秒。
- 事务一致性:快照一致,但快照 Ts 受 Lightning safe-ts 限制。
- 弹性扩展:Lightning 作为独立服务可以按分析工作负载单独扩。
F1 Lightning 的启示是:当底层事务存储无法改动时,HTAP 可以以”官方 CDC + 列存 service”的形式解耦存在。代价是新鲜度比 TiFlash 的 Raft Learner 路线差一档——它不是直接从共识日志上拉,而是从 Spanner 的变更流拉,中间多一跳 changepump。
4.3 和 TiFlash 的对比
F1 Lightning 与 TiFlash 表面都是 “行存 + 列存副本”,但同步层不同:
| 维度 | TiFlash | F1 Lightning |
|---|---|---|
| 同步通道 | Raft Learner 日志 | changepump(基于 Spanner 变更流) |
| 新鲜度 | 亚秒级 | 秒级 |
| 与事务层耦合度 | 紧(同一 Region 的 Raft group) | 松(独立服务) |
| 上线成本 | 需要部署 TiFlash 节点 | 需要 Lightning + changepump |
| 适配存量系统 | 仅 TiDB | 可扩展到多个前端事务系统 |
两者的工程哲学差别:TiDB 是”一个项目全栈自研 HTAP”,F1 Lightning 是”给已有事务系统加 HTAP 插件”。
五、Lakehouse:当 OLAP 存储自己支持更新
5.1 Delta Lake 与 Iceberg 的 HTAP 含义
Armbrust 等人在 CIDR 2021 的论文 “Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics” 提出 Lakehouse 概念:在对象存储上直接构建具备 ACID、Schema 演化、时间旅行能力的表格式,代表是 Delta Lake、Apache Iceberg、Apache Hudi。
Lakehouse 与传统 HTAP 的根本差异:它不要求 OLTP 和 OLAP 共享同一份运行时存储,而是接受 OLTP 仍然在外部事务系统里跑,只让 OLAP 存储具备”可更新、可删除、可回溯”的能力,再通过 CDC 入湖或直接写入使”分析侧的存储”也能承载轻量事务写入。
核心机制:
- 事务日志:Delta Lake 的
_delta_log/、Iceberg 的 manifest list,每次写入产生一个 JSON/Avro 日志条目,记录新增/删除的数据文件; - 乐观并发控制:多个写入者同时提交,冲突靠日志版本号比较决定谁胜出;
- MERGE 与 UPDATE:通过 copy-on-write 或 merge-on-read 实现行级更新(Hudi 同时支持两者);
- 时间旅行:基于日志版本号或时间戳回溯到任意历史快照。
5.2 Lakehouse 不是 HTAP 的全部替代
Lakehouse 的”事务”语义比 OLTP 弱:
- 每次写入是批处理事务,单次提交动辄几 MB 到几 GB;
- 点查延迟取决于对象存储的元数据开销,通常几十毫秒到秒级;
- 乐观并发在高冲突写入下会大量回退重试;
- 没有行锁、没有长事务语义,不支持多语句交互式事务。
所以 Lakehouse 不是”把 MySQL 替掉”,而是”把下游 OLAP 副本从’不可更新的 Parquet 集’升级为’可事务更新的 Parquet 集’“。它和前面三种 HTAP 方案的关系是互补的:OLTP 继续由 MySQL / PostgreSQL / TiDB 承担,Lakehouse 承担”近实时分析 + 机器学习特征 + 历史回溯”。
5.3 坐标系定位
- 隔离方式:完全分离,OLTP 与 Lakehouse 通常在不同存储系统。
- 新鲜度档位:秒级到分钟级,取决于 CDC 入湖频率与小文件合并策略。
- 事务一致性:快照一致,写入原子但不提供跨系统事务。
- 弹性扩展:存储与计算彻底解耦,计算按查询规模临时拉起。
5.4 行列双维护下的 freshness 边界
把这几类 HTAP 放在同一个 freshness 坐标轴上,可以画出一条粗略的谱系:
freshness
(越往右越新)
|
| Lakehouse (CDC 入湖)
|--------------- 分钟级
| F1 Lightning
|--------------- 秒级
| TiDB + TiFlash
|--------------- 亚秒级
| SingleStore Universal
|--------------- 事务提交即可见
|
v 隔离强度(上强下弱)
越往上,OLTP / OLAP 物理隔离越彻底;越往下,隔离越弱但新鲜度越高。这条谱系不是”越新越好”:对报表场景,秒级已经够用;对实时风控、库存一致性场景,才必须下沉到”事务可见即可读”。
六、如何测 HTAP 系统:CH-benCHmark 与 HATtrick
6.1 CH-benCHmark
Cole 等人在 2011 年提出的 CH-benCHmark 是 HTAP 领域最早、也是最流行的混合基准。它把 TPC-C(事务)和 TPC-H(分析)拼到同一张数据集上:TPC-C 负责持续生成事务,TPC-H 的 22 个分析查询在同一份数据上并发运行。
CH-benCHmark 关心两组指标:
- TPC-C 侧:tpmC(每分钟新订单数),延迟 p99;
- TPC-H 侧:每个查询的响应时间,以及并发执行时的整体吞吐。
关键点在于”并发”:OLAP 查询必须和 OLTP 同时跑,观察两侧是否会互相干扰。一个 HTAP 系统即便 OLTP 单独跑很快、OLAP 单独跑也很快,只要并发时互相拖慢超过 20–30%,就说明工作负载隔离做得不好。
6.2 HATtrick
HATtrick(Sirin 等人,ICDE 2021 附近的系列工作)在 CH-benCHmark 基础上改进了两点:
- 可调的分析/事务比例:允许用参数控制分析查询的并发度,扫掉 CH-benCHmark 固定为 “1 个 OLAP 客户端 + N 个 OLTP 客户端” 的局限;
- 新鲜度测量:明确给出”事务提交到分析查询可见”的时延分布,把上一节的”freshness 坐标”从概念变成可测数字。
HATtrick 的流程大致是:
- 事务端定期插入带时间戳的”探针行”;
- 分析端定期扫表计算”最大探针时间戳”;
- 两者的差值即新鲜度 lag。
这一指标几乎比任何”平均查询延迟”都更能反映 HTAP 系统的真实能力。
6.3 基准测试的常见盲点
照搬论文基准时要小心:
- 数据集规模不代表真实压力。TPC-C 的 WH=100 只有约 10 GB 数据,TiFlash 在这个规模下 compaction 几乎不工作,实际生产规模(数百 GB 到 TB)表现完全不同。
- TPC-H 的 22 个查询偏向静态分析,不覆盖交互式 BI 的”很多轻查询”场景。对交互式 BI,更合适的是自建 query log replay。
- 忽略 DDL 与 schema 变更。真实系统的 HTAP 路径在加列、改类型、加索引时最容易出问题。
- 只测稳态,不测扩缩容。列存副本扩容时的数据搬迁、safe-ts 重建代价,在任何标准基准里都没有直接体现。
6.4 自建基准的几个建议
真正要评估 HTAP 系统,建议在 CH-benCHmark 基础上自建一个小工具集,包含:
- 可调并发模型:能按时间段切换 “纯 OLTP / 纯 OLAP / 混合” 三种模式,看互相干扰;
- 突发负载:从稳态突然注入 10× 的分析查询,观察 OLTP p99 是否崩;
- 长事务探针:注入一个持续 10–30 分钟的长事务,看分析侧是否被拖慢、存储侧是否因为 MVCC 版本链过长放大延迟;
- DDL 搅动:在压测中途加列、改类型,看两侧副本是否同步完成、是否有错误数据;
- 故障注入:kill 一个 TiFlash 节点,观察 safe-ts 推进和查询失败率。
比起只看一个 tpmC / QphH 数字,这些微基准更能暴露一个 HTAP 系统的真实工程质量。
七、选型决策:我到底需不需要 HTAP
7.1 一个简单的决策树
问题:分析报表对事务数据的新鲜度要求?
├── 分钟级及以上 -> 不要 HTAP,上 Lakehouse/数仓 + CDC
│
├── 秒级 -> 优先考虑 F1 Lightning 式的"外挂列存 service";
│ 小规模可以直接 TiDB + TiFlash
│
├── 亚秒级 -> TiDB + TiFlash、OceanBase;
│ 或 SingleStore Universal Storage
│
└── 事务提交即可见 -> SingleStore Universal Storage、SAP HANA;
接受单点扩展上限
另一条维度是隔离强度:
- 要求 OLAP 不能影响 OLTP p99 ≥ 5% -> 必须物理副本,TiDB + TiFlash / F1 Lightning;
- 能接受轻度互相影响 -> SingleStore 类型一体化方案;
- 完全可接受离线影响 -> Lakehouse。
7.2 常见的”假 HTAP 需求”
在咨询和 code review 里,有些 HTAP 需求其实不成立:
- “我们要实时报表,用 HTAP 吧。” 先问报表查询的 QPS 和数据量。如果只是一个 dashboard,每分钟刷一次、扫几百万行,直接在 TiDB/MySQL 上建物化视图或上 Lakehouse 就够了,不必引入列存副本。
- “我们 OLTP 很慢,加个列存加速一下。” 点查变慢通常是索引/缓存/锁问题,列存加不进来。
- “我们分析查询很慢,加个 HTAP 副本。” 如果分析查询是”从 1 亿行里找 10 行”,这是索引问题不是列存问题;只有扫描量占表的很大比例时列存才明显更快。
判断是否真需要 HTAP 的一个简单启发:把 OLAP 查询的扫描行数 / 查询结果行数 算一下,如果比值 ≥ 1000,列存大概率有收益;如果 ≤ 10,加索引就够了。
7.3 与本仓库其它文章的互链
- 事务侧的一致性模型见《一致性模型》;
- Raft 日志如何被 Learner 消费见《Raft 深度解析》;
- 列存的底层编码见《列式存储原理》与《Parquet 文件格式》;
- Lakehouse 的存算分离思路,在《Disaggregated DB 合集》里还会再见。
7.4 迁移与回滚
HTAP 不是一次性决策,而是一段演进过程。常见迁移路径:
- 纯 OLTP + 外部数仓(起点):MySQL/PostgreSQL 做事务,夜间 ETL 到 Hive/ClickHouse。
- CDC 实时入湖:Debezium / Maxwell 把 binlog 实时推入 Kafka + Lakehouse,分析侧从分钟级降到秒级。
- 引入列存副本:对核心业务表加 TiFlash 副本或用 SingleStore Universal Storage,分析侧 join 事务表变快。
- 统一查询入口:通过查询代理(如 F1 Query、Presto / Trino 连到多数据源)让应用不感知底层存储差异。
回滚也要预留:每一步都要可以独立关掉。尤其第 3 步,列存副本出问题时要能快速切回”只读 OLTP” 兜底,不能全线崩。很多踩坑的团队就是因为一开始没想好回滚路径,到问题爆发时只能硬扛。
八、demo 与工程实验建议
本目录下 demo/ 放一个最小的 CH-benCHmark
运行脚本(基于 benchbase 或
go-tpc),用
Docker Compose 启动一个 TiDB + TiFlash 单机集群,跑 WH=10 的
TPC-C 同时并发一个 TPC-H Q6。观察:
- TiFlash 的 safe-ts lag(通过
information_schema.tiflash_replica); - TiKV 节点 CPU vs TiFlash 节点 CPU;
- 加 TiFlash 副本前后 Q6 响应时间变化。
这不是标准 HATtrick,但对”理解一次真实的 HTAP
调度”足够。docker-compose.yml 与运行说明见
demo/README.md。
九、小结
HTAP 不是单一方案,而是一组围绕”一份数据 × 两类负载”的工程取舍:
- TiDB + TiFlash:Raft Learner 路线,物理副本、亚秒级新鲜度、行列独立扩展,适合”事务写入由 TiDB 承担、同时要近实时分析”的场景。
- SingleStore Universal Storage:一体化路线,行列共存、事务提交即可见,适合中等规模、需要极低 lag 的 HTAP 工作负载。
- F1 Lightning:外挂路线,CDC + 列存 service,适合改不动底层事务系统但又要统一查询入口的场景。
- Lakehouse:分离路线,OLTP 在外、OLAP 存储自身具备事务语义,适合”分析才是主战场、事务交给别人”的平台型产品。
读论文与做选型时,先用第一节给出的四维坐标(隔离 / 新鲜度 / 一致性 / 弹性)定位,再按第七节的决策树做取舍,能避免大部分”选了 HTAP 又后悔”的情况。
最后提醒一点:HTAP 是 2015 年之后才开始被严肃工程化的话题。很多结论仍然在演变,本文归纳的四种模式也不一定能覆盖 5–10 年后的全部情况。与其记住具体论文,不如记住分析方法:任何一个自称”HTAP” 的系统,都可以用”它在新鲜度坐标的哪一档、它的工作负载隔离做到哪一层、它怎么测”这三个问题拆开看。
参考文献
- Huang D., et al. TiDB: A Raft-based HTAP Database. VLDB 2020. https://www.vldb.org/pvldb/vol13/p3072-huang.pdf
- Yang J., et al. F1 Lightning: HTAP as a Service. VLDB 2020. https://www.vldb.org/pvldb/vol13/p3313-yang.pdf
- Armbrust M., et al. Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics. CIDR 2021. https://www.cidrdb.org/cidr2021/papers/cidr2021_paper17.pdf
- Armbrust M., et al. Delta Lake: High-Performance ACID Table Storage over Cloud Object Stores. VLDB 2020. https://www.vldb.org/pvldb/vol13/p3411-armbrust.pdf
- Cole R., et al. The Mixed Workload CH-benCHmark. DBTest 2011.
- Sirin U., et al. A Methodology for Performance Analysis of Mixed OLTP/OLAP Workloads. (HATtrick 相关工作)
- SingleStore Documentation. Universal Storage. https://docs.singlestore.com/
- Corbett J. C., et al. Spanner: Google’s Globally-Distributed Database. OSDI 2012.
上一篇:【数据库研究前沿】多模态数据库
下一篇:【数据库研究前沿】Serverless 数据库弹性理论:Neon 与 Aurora Serverless v2
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【数据库研究前沿】系列导论:从 System R 到 AI-Native 的 2026 研究地图
以 System R、Postgres、Bigtable、Spanner、Snowflake 等关键节点串起 50 年数据库史,勾勒 2026 年 AI-Native、向量检索、HTAP 云原生、新硬件、隐私计算、新范式、方法论七条主线,并给出 25 篇系列文章的完整阅读地图。
【数据库研究前沿】湖仓一体一致性模型:Iceberg、Delta、Hudi 的事务边界
从 metadata layout、快照隔离、多写者协议、schema/partition evolution 四个维度重读 Apache Iceberg、Delta Lake、Apache Hudi,给出选型矩阵与湖仓一体在对象存储上的事务边界
【数据库研究前沿】如何读数据库顶会论文:SIGMOD/VLDB/CIDR 阅读路线
从顶会定位、检索渠道、三遍读法到工业与学术论文的辨别方法,给出 2023–2025 年数据库领域可信必读二十篇,并配套 CMU 15-721、Stanford CS 245 等公开课清单。
【数据库研究前沿】学习型查询优化器:Neo、Bao、Balsa 到 LLM-CBO
系统梳理 Neo、Bao、Balsa 以及新兴 LLM-assisted 查询优化的核心思想,结合 PostgreSQL pg_hint_plan 给出一条可落地的 learned QO 工程路径