【TiKV / HTAP 内核】raftstore 写路径:propose 到 Apply

💡 原文中文,约12100字,阅读约需29分钟。
📝

内容提要

TiKV 的写请求经历四个阶段:propose、append、commit 和 apply。commit 阶段确保日志被多数副本持久化,但不代表数据已写入 RocksDB。apply 阶段负责实际写入。TiKV 通过异步设计提高性能,确保协议推进与状态机执行分离,优化写入效率。

🎯

关键要点

  • TiKV 的写请求经历四个阶段:propose、append、commit 和 apply。

  • commit 阶段确保日志被多数副本持久化,但不代表数据已写入 RocksDB。

  • apply 阶段负责实际写入数据到 RocksDB。

  • TiKV 通过异步设计提高性能,确保协议推进与状态机执行分离,优化写入效率。

  • commit 只依赖多数副本完成 append,不依赖任何副本完成 apply。

  • TiKV 将 propose/append/commit 交给 raftstore 线程处理,将 apply 交给独立的 apply 线程池处理。

  • apply 线程池在写入 RocksDB 时,会同时更新 RaftApplyState 以确保崩溃恢复的一致性。

  • 写路径的四个阶段是不可省略的,读路径存在优化空间。

  • TiKV 的设计遵循了复制状态机模型,分离了协议达成一致与状态机执行的过程。

🔎

延伸解读

写请求的四个阶段

TiKV 的写请求经历 propose、append、commit 和 apply 四个阶段。理解这些阶段的区别对于排查写延迟问题至关重要。commit 阶段确保日志在多数副本上持久化,但并不意味着数据已写入 RocksDB,apply 阶段才是实际写入数据的过程。

异步设计的优势

TiKV 通过将 commit 和 apply 阶段分离,采用异步设计来提高性能。这种设计允许 Raft 协议的推进与状态机的执行独立进行,从而避免了写入延迟对协议推进的影响。这种解耦设计是 TiKV 高效处理写请求的关键。

崩溃恢复的一致性

在 apply 阶段,TiKV 不仅写入用户数据,还更新 RaftApplyState,以确保崩溃恢复的一致性。将 apply_state 与用户数据在同一 WriteBatch 中原子提交,避免了因断电导致的状态不一致问题,这是 TiKV 设计中的重要细节。

延伸问答

TiKV 的写请求经历哪些阶段?

TiKV 的写请求经历四个阶段:propose、append、commit 和 apply。

commit 阶段的作用是什么?

commit 阶段确保日志被多数副本持久化,但不代表数据已写入 RocksDB。

apply 阶段的主要任务是什么?

apply 阶段负责将日志中的操作真正执行并写入本地的 RocksDB 状态机。

TiKV 如何提高写请求的性能?

TiKV 通过异步设计提高性能,确保协议推进与状态机执行分离,优化写入效率。

为什么 commit 和 apply 阶段是独立的?

commit 和 apply 阶段是独立的,以避免 apply 阶段的延迟影响 Raft 协议的推进速度。

TiKV 的写请求成功后,客户端何时收到确认?

客户端在本 Region 的 apply 完成后收到写成功的确认。

🏷️

标签

➡️

继续阅读