【分布式系统百科】分布式 KV 存储对比:etcd、TiKV 与 FoundationDB

💡 原文中文,约24800字,阅读约需59分钟。
📝

内容提要

本文对比了etcd、TiKV和FoundationDB三种分布式键值存储系统。etcd适合小规模元数据存储,提供Watch和Lease机制;TiKV支持PB级数据水平扩展和分布式事务;FoundationDB提供严格可串行化事务和确定性模拟测试。选型需根据数据量、事务需求和一致性要求决定。

🔎

延伸解读

选型先看数据规模与事务需求

文章明确指出,etcd 适合 2GB 以下、QPS 低于 1 万的元数据场景,TiKV 面向 PB 级数据并提供分布式事务,FoundationDB 则强调严格可串行化。选型时应先评估数据量是否超过 etcd 上限,再判断是否需要跨节点事务,最后根据一致性要求(快照隔离或严格可串行化)在 TiKV 与 FoundationDB 之间取舍。

一致性级别与延迟的权衡

三者一致性级别不同:etcd 提供线性一致性但线性读延迟 10-20ms;TiKV 默认快照隔离,点读延迟 1-5ms;FoundationDB 严格可串行化,写延迟 15-25ms。强一致性往往带来更高写延迟,而快照隔离可能产生写偏斜。理解这些权衡有助于根据业务对延迟和一致性的敏感度做出选择。

注意各系统的运维与扩展瓶颈

etcd 受单 Raft 组限制,写吞吐约 1 万 QPS,且需定期处理压缩与碎片整理;TiKV 需关注 Region 数量、热点和 PD 可用性;FoundationDB 有 5 秒事务和 10MB 大小限制,且运维角色多。部署前应评估团队运维能力,并针对瓶颈设计应对方案。

Q&A

etcd、TiKV 和 FoundationDB 在架构上有什么主要区别?

etcd 采用单 Raft 组,所有数据由一个 Raft 实例管理,适合小规模元数据存储;TiKV 采用 Multi-Raft,将数据按范围划分为多个 Region,每个 Region 独立 Raft 组,支持水平扩展;FoundationDB 采用分层架构,将事务处理与存储分离,由 Sequencer、Proxy、Resolver、Log Server 和 Storage Server 等角色组成,提供严格可串行化事务。

etcd 的 Watch 机制是如何工作的?

etcd 的 Watch 机制允许客户端监听某个 key 或前缀的变更事件,基于 MVCC 的历史版本实现。当 Watcher 指定起始 Revision 时,etcd 从该 Revision 开始回放所有变更,保证事件按 Revision 顺序投递,不丢失、不乱序。

TiKV 如何实现分布式事务?

TiKV 的分布式事务基于 Google Percolator 模型,采用两阶段提交(2PC)和快照隔离。事务开始时从 PD 获取 start_ts,读取时使用该时间戳进行快照读;提交时先 Prewrite 写入所有修改并加锁,然后从 PD 获取 commit_ts,先提交 Primary Key,再异步提交 Secondary Key。

FoundationDB 的确定性模拟测试是什么?

FoundationDB 的确定性模拟测试框架将网络、磁盘、时钟等非确定性操作抽象为可替换接口,在测试时用确定性模拟实现替换,可以在单进程中模拟完整的多节点集群,并注入网络分区、进程崩溃等故障。由于所有操作是确定性的,发现 bug 后可以用相同随机种子精确重放故障序列,极大降低调试难度。

etcd、TiKV 和 FoundationDB 分别适合什么场景?

etcd 适合小规模元数据存储、服务发现、分布式锁和配置中心,数据量小于 2GB,QPS 低于 1万;TiKV 适合大规模键值存储、需要分布式事务的场景,以及作为 TiDB 的存储后端,支持 PB 级数据;FoundationDB 适合需要严格可串行化事务、构建自定义数据模型、对可靠性要求极高的场景,如金融、计费系统。

etcd 的线性读和串行读有什么区别?

etcd 的线性读需要经过 Raft 确认 Leader 身份有效,延迟较高(10-20ms),但保证读到最新已提交的数据;串行读直接从本地状态机读取,延迟低(<1ms),但可能读到过期数据。

TiKV 的 Region 是什么?

TiKV 将整个 key 空间按范围划分为多个 Region,默认每个 Region 96MB。每个 Region 对应一个独立的 Raft 组,拥有自己的 Leader 和 Follower 副本,不同 Region 的 Raft 日志复制并行执行,这是 TiKV 实现水平扩展的核心机制。

FoundationDB 的 5 秒事务限制是什么?

FoundationDB 强制要求每个事务必须在 5 秒内完成,这是刻意的设计决策,以保证系统在任何故障后都能在有界时间内完成恢复。长事务会阻碍恢复,因此应用需要将大操作拆分为多个小事务。

🏷️

标签

➡️

继续阅读