本系列从 Region 模型、Multi-Raft 写到 raftstore 写路径、PD/TSO、Percolator 事务、Coprocessor 下推、TiFlash Learner 与新鲜度,再到 CockroachDB 对照和生产排障。读者读到这里应该已经能回答”一次 Put 怎么经 Multi-Raft 落到 RocksDB”“TiFlash 的新鲜度边界在哪”这类问题。本文是系列第 18 篇(末篇),收束成三件事:一张扩展选型决策树、站内阅读地图、全系列的学术谱系与开放问题。
一、选型决策树:我到底该用哪一层
flowchart TD
START["Need a KV store"]
START --> Q1{"Data size < 2 GB and<br/>need Watch/Lease semantics?"}
Q1 -->|yes| ETCD["etcd<br/>cluster metadata, service discovery"]
Q1 -->|no| Q2{"Need distributed transaction<br/>across many keys?"}
Q2 -->|no| Q3{"Single process embedded,<br/>no cross-node scaling needed?"}
Q3 -->|yes| ROCKSDB["Single-node RocksDB<br/>embedded KV, see rocksdb series"]
Q3 -->|no| ETCD
Q2 -->|yes| Q4{"Need strict serializability<br/>and flexible data model layers?"}
Q4 -->|yes| FDB["FoundationDB<br/>OCC + strict serializability"]
Q4 -->|no| Q5{"Need SQL layer + snapshot isolation<br/>at PB scale?"}
Q5 -->|yes| TIKV["TiKV (+ TiDB)<br/>Multi-Raft + Percolator"]
Q5 -->|no| Q6{"Need row-store-like consistency<br/>plus analytics on same data?"}
Q6 -->|yes, near-real-time acceptable| TIFLASH["TiKV + TiFlash Learner<br/>见第 14-15 篇"]
Q6 -->|no, freshness in minutes OK| LAKE["Lakehouse + CDC<br/>Iceberg/Delta + Debezium/Kafka"]
1.1 路径说明
| 场景 | 首选 | 依据 |
|---|---|---|
| 集群元数据、服务发现、分布式锁 | etcd | 单 Raft 组,容量上限约 2–8 GB,Watch/Lease 是核心卖点(distributed/39) |
| PB 级分布式事务 KV,需要 SQL | TiKV + TiDB | Multi-Raft 水平扩展 + Percolator 事务(本系列第 3–11 篇) |
| 严格可串行化,需要自定义数据模型层 | FoundationDB | OCC + Strict Serializability,Layer 架构(distributed/39) |
| 单机/嵌入式,无需跨节点扩展 | 单机 RocksDB | 写优化 LSM,进程内嵌入(rocksdb 系列) |
| 同一份数据要兼顾 OLTP 与近实时分析 | TiKV + TiFlash | Raft Learner 列存副本,新鲜度”准实时”档(第 14–15 篇) |
| 分析为主战场,事务交给别的系统,新鲜度分钟级可接受 | 湖仓 + CDC | Iceberg/Delta + Debezium/Kafka,见 db-frontier/12 §五 |
1.2 何时不选 TiKV
- 数据量小于 2 GB、只需要配置/协调语义 → 上 etcd,不必为此部署 PD + TiKV 一整套分布式存储;
- 只是单机应用需要一个内嵌 KV → 直接用 RocksDB,不需要 Raft、不需要跨节点;
- 需要严格可串行化(Strict Serializability)且能接受更高运维复杂度 → 评估 FoundationDB,TiKV 默认的快照隔离弱于可串行化,无法防止写偏斜(Write Skew);
- 分析才是主战场,事务型写入本就轻量或由别的系统承担 → 优先考虑湖仓 + CDC,不必为了”顺便做分析”引入 TiFlash 的运维成本。
1.3 何时该选 TiKV(+ TiFlash)
- 已经在用或计划用 TiDB 作为分布式 SQL 层,需要与之匹配的存储引擎;
- 需要跨 key、跨 Region 的分布式事务,且快照隔离级别可以接受;
- 需要在同一份数据上支持”事务写入 + 近实时分析”,且能接受亚秒级到秒级的可见时延(第 15 篇已定义 safe-ts 边界)。
1.4 最小故事:三类典型落点
| 场景 | 你会选什么 | 本系列哪几篇最关键 |
|---|---|---|
| K8s 控制面、服务注册、配置中心 | etcd | 本篇决策树;不必读 02–15 |
| Flink 状态、单机服务内嵌 KV | RocksDB | rocksdb 系列;本篇 §1.2 |
| 分布式 SQL + 近实时报表 | TiKV + TiFlash | 03–06、09–11、14–15、17 |
| 严格可串行化 + 自定义 Layer | FoundationDB | distributed/39 |
| 分析为主、事务在别处、分钟级新鲜度可接受 | 湖仓 + CDC | lakehouse 19、db-frontier/12 §五 |
flowchart LR
subgraph oltp ["OLTP path"]
tidb["TiDB SQL"]
tikv["TiKV row store"]
tidb --> tikv
end
subgraph olap ["OLAP path near-real-time"]
tiflash["TiFlash Learner"]
tikv -->|"Raft log"| tiflash
end
subgraph lake ["OLAP path CDC minutes"]
cdc["CDC / Kafka"]
iceberg["Iceberg table"]
oltp -.->|"async"| cdc --> iceberg
end
「要不要 HTAP」不是口号问题,而是新鲜度档位问题:db-frontier/12 把档位分成 CDC 型、准实时、完全实时三档;TiKV+TiFlash 落在准实时——比湖仓 CDC 快,比 SingleStore 一体存储的「提交即可见」弱。选型时先定档位,再选组件,而不是先选 TiDB 再倒推业务能否接受 safe-ts。
二、站内阅读地图
flowchart LR
RAFT["distributed/raft-explained<br/>Raft protocol"]
ROCKS["rocksdb series<br/>single-node LSM"]
PERC["distributed/30<br/>Percolator model"]
REBAL["distributed/27<br/>rebalancing"]
KVCMP["distributed/39<br/>etcd/TiKV/FDB compare"]
FRONTIER["db-frontier/12<br/>HTAP paradigms"]
COL["columnar-engine<br/>ClickHouse/DuckDB"]
QE["query-engine<br/>MPP execution"]
subgraph SERIES["This series: TiKV / HTAP kernel (18 篇)"]
direction TB
P1["01-06 Region/Multi-Raft/write path"]
P2["07-11 PD/TSO/Percolator"]
P3["12-18 Coprocessor/TiFlash/compare/select"]
P1 --> P2 --> P3
end
RAFT --> P1
ROCKS --> P1
PERC --> P2
REBAL --> P2
KVCMP --> P3
FRONTIER --> P3
COL --> P3
QE --> P3
2.1 推荐阅读路径(回顾系列 index 的路径表)
| 目标 | 路径 |
|---|---|
| 快速建立坐标系 | 1 → 3 → 4 → 5 → 9 → 10 → 14 → 本篇 |
| 从 RocksDB 单机上来 | 1 → 2 → 5 → 10 → 本篇 |
| 从 Raft 协议来 | 4 → 5 → 6 → 14 → 16 |
| 排查锁冲突/热点 | 2 → 9 → 10 → 11 → 17 |
| HTAP / 分析下沉 | 1 → 14 → 15 → 本篇 |
| 完整通读 | 1 → … → 18 |
三、学术谱系收束
| 主题 | 奠基 / 代表文献 | 会议·年份 | 本系列落点 |
|---|---|---|---|
| Raft 共识 | Ongaro & Ousterhout, In Search of an Understandable Consensus Algorithm | USENIX ATC 2014 | 第 4–6 篇(只引安全不变量,不重讲全文) |
| LSM-Tree | O’Neil et al., The Log-Structured Merge-Tree | Acta Informatica 1996 | rocksdb 系列外链,本系列第 1–2 篇 |
| 分布式事务落地 | Peng & Wei, Large-scale Incremental Processing Using Distributed Transactions and Notifications(Percolator) | OSDI 2010 | 第 10–11 篇 |
| 外部一致性授时 | Corbett et al., Spanner: Google’s Globally-Distributed Database | OSDI 2012 | 第 9、15 篇对照 |
| HTAP Raft Learner | Huang et al., TiDB: A Raft-based HTAP Database | VLDB 2020 | 第 1、14、15 篇核心锚点 |
| range+Raft 对照系统 | Taft et al., CockroachDB: The Resilient Geo-Distributed SQL Database | SIGMOD 2020 | 第 16 篇 |
| 提交协议延伸 | CockroachDB Parallel Commits(工程博客/RFC) | 2018–2020 | 第 16 篇,标注为工程设计文档而非同行评审论文 |
争论仍活跃、无定论:单进程一体化(CockroachDB/OceanBase)与分离式部署(TiDB/TiKV/PD)在长期运维成本上谁更优,缺乏公开的、控制变量的对比研究(第 16 篇 §七已标注);HTAP 是否应该走”双引擎 + Learner 同步”还是”单一存储引擎兼顾行列”,db-frontier/12 已给出四条路线对比,本系列在 TiFlash 一侧补齐了 Raft Learner 工程细节,但顶会尚无”何种路线绝对更优”的共识。
四、系列完成状态
| 部分 | 篇目 | 核心内容 |
|---|---|---|
| 全景与本地引擎 | 01–04 | HTAP 四件套全景、Key 编码与 MVCC、Region 模型、Multi-Raft |
| 写路径与副本 | 05–06 | raftstore 写路径、Snapshot/log GC |
| PD 与时间戳 | 07–09 | PD 调度、Split/Merge/热点、TSO |
| 事务 | 10–11 | Percolator 乐观事务、悲观事务与 ResolveLock |
| 计算下推与 SQL 边界 | 12–13 | Coprocessor DAG 下推、TiDB SQL 层边界 |
| TiFlash 与对照 | 14–16 | TiFlash Learner、新鲜度与一致性、CockroachDB 对照 |
| 排障与选型 | 17–18 | 生产排障决策树、本篇选型收束 |
全系列围绕”Region 切分 → Multi-Raft 复制 → PD 调度/TSO → Percolator 事务落地 → Coprocessor/SQL 边界 → TiFlash/选型”的主线组织,与 rocksdb(单机 LSM)、raft-explained(协议教科书)、db-frontier/12(HTAP 范式综述)三篇既有内容分工明确、互不重复。
五、开放问题(全系列收束)
- 千万级 Region 的运维上限:第 17
篇给出的 Region 过多排障信号,本质上是在逼近”单 PD
实例能管理多少 Region
元信息”的工程上限;社区在持续优化(Hibernate Region、Region
Merge、
use-region-storage),但公开资料未给出一个可外推到所有硬件配置的通用上限数字。 - safe-ts 的跨 Region 聚合可观测性:第 15 篇已指出,大表跨多个 Region 时,用户看到的”表级新鲜度”是所有相关 Region safe-ts 的下确界,但这一聚合口径目前没有统一的运维监控规范。
- 单进程一体化 vs 分离式部署的长期成本:第 16 篇已标注这是缺乏受控实验支撑的架构哲学争论,本系列不下结论。
- 双引擎 HTAP(TiKV+TiFlash)与统一存储 HTAP(SingleStore/OceanBase 一体存储)谁的长期工程复杂度更低:db-frontier/12 给出过坐标系(隔离方式、新鲜度档位、一致性、弹性扩展),但顶会文献目前只给出各自的设计取舍,没有给出”应该收敛到某一种范式”的证据。
以上问题不承诺”未来会统一”或”下个版本会解决”——它们是当前公开资料(官方文档、论文、工程博客)能够支撑的已知边界,留给读者在实际选型和二次调研时继续跟踪。
六、常见误解
误解一:TiKV 能替代所有分布式 KV 场景,包括做 Kubernetes 的元数据存储。 不合适。TiKV 面向 PB 级数据与分布式事务设计,比 etcd 重得多;Kubernetes 需要的是小数据量、强 Watch 语义、快速选举恢复,etcd 仍是更匹配的选择(distributed/39已有系统对照)。
误解二:读完本系列就能替代 TiKV/PD/TiFlash 官方文档和源码。 本系列钉的是机制与工程链路——Region 怎么切、日志怎么 apply、新鲜度边界在哪;具体参数取值、版本间差异、API 细节仍以官方文档和源码当前版本为准,本系列不承诺覆盖版本演进的全部细节。
误解三:选型就是比拼吞吐数字。 本系列全程没有给出跨系统的吞吐排名——不同系统的一致性级别、事务模型、部署形态都不同,脱离工作负载和一致性要求的裸吞吐对比没有意义。选型应该按第一节的决策树,先确定一致性、事务、新鲜度的硬约束,再在满足约束的候选里比工程成本。
七、小结
三句话小结:
- 选型先问三件事——数据规模、是否需要跨 key 分布式事务、新鲜度要求——再落到 etcd / TiKV / FoundationDB / 单机 RocksDB / 湖仓+CDC 中的具体一档,不是比拼营销吞吐数字。
- 本系列 18 篇建立的主线是”Region 切分 → Multi-Raft 复制 → PD/TSO → Percolator 事务 → Coprocessor/SQL 边界 → TiFlash/新鲜度”,与 rocksdb、raft-explained、db-frontier/12 三篇已有内容分工明确。
- 千万级 Region 运维上限、safe-ts 跨 Region 聚合可观测性、单进程与分离式部署的长期成本,仍是本系列标注但未解决的开放问题,留给读者持续跟踪官方文档与顶会讨论。
参考资料
- 本系列 第 1–17 篇 及 PLAN.md(写作执行文档,非发布页)。
- distributed/39 分布式 KV 存储对比(etcd/TiKV/FoundationDB 完整对照)。
- db-frontier/12 HTAP 新范式(HTAP 四条路线坐标系,本系列在 TiFlash 一侧补齐工程细节)。
- rocksdb 内核系列、raft-explained(先修内容,不在本系列重复)。
- Huang D., et al. TiDB: A Raft-based HTAP Database. VLDB 2020;Peng D., Dabek F. Percolator, OSDI 2010;Taft R., et al. CockroachDB, SIGMOD 2020;Ongaro D., Ousterhout J. Raft, USENIX ATC 2014(核心论文清单,详细引用见对应章节)。
- 数据库内核索引、全部系列索引。
感谢读完本系列。TiKV / HTAP 内核系列至此完结,返回 系列目录 查看全 18 篇,或回到 数据库内核索引 探索其它系列。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【RocksDB 内核机制】选型与存储栈阅读地图
用决策树收束 RocksDB 与 InnoDB、列存、湖仓的适用边界;给出存储引擎三角 + 数据平台全栈阅读地图,对接 query-engine/18 与 postgresql-kernel,并标注 HTAP/TiKV 续作入口。
【Redis / 缓存内核】选型与阅读地图:standalone · Sentinel · Cluster · Valkey
用决策树收束 standalone、Sentinel、Cluster 与纯缓存分工,简述 Valkey ABI 社区分叉与 Redis 模块边界,列出多线程与持久化争论,并给出回到本系列、architecture/17 与 RocksDB 的阅读地图以闭合全系列。
【TiKV / HTAP 内核】HTAP / 分布式 KV 全景:TiDB–TiKV–PD–TiFlash 四件套
定位 TiKV 7.x/8.x 在 RocksDB 单机 LSM、Raft 协议与 HTAP 范式之间补的那一层:TiDB、TiKV、PD、TiFlash 四组件各自的抽象边界,以及本系列 18 篇的读法。
【TiKV / HTAP 内核】Key 编码与 MVCC:三 CF 与时间戳
拆解 TiKV 的 user key + start_ts/commit_ts 编码规则与 default/lock/write 三 CF 分工,并说明为什么这套 MVCC 与 RocksDB Snapshot 的 sequence 号是两层完全不同的机制。