在学习了之前的几篇 raft-rs, raftstore 相关文章之后(如 Raft Propose 的 Commit 和 Apply 情景分析,Raftstore 概览等),raft-rs 以及 raftstore 的流程大家应该基本了解了。其中 raft-rs 解决的是单个 Raft group(即单个 Region) 的问题,raftstore 解决的是多个 Raft group (即多个 Region)的问题。Split 和 Merge 则是 raftstore 多个 Raft group 所独有的操作。 TiKV 中的 Split 能把一个 Region 分裂成多个 Region,Merge 则能把 Range 相邻的 2 个 Region 合成一个 Region。本文接下来要介绍的是 Split 的源码。
Region epoch
message RegionEpoch {
// Conf change version, auto increment when add or remove peer
uint64 conf_ver = 1;
// Region version, auto increment when split or merge
uint64 version = 2;
}
我们先从 region epoch 讲起,上面是它的 protobuf 定义,在之前的源码分享文章中提到过,它的本质就是两个版本号,更新规则如下:
-
配置变更的时候,
conf_ver+ 1。 -
Split 的时候,原 region 与新 region 的
version均等于原 region 的version+ 新 region 个数。 -
Merge 的时候,两个 region 的
version均等于这两个 region 的version最大值 + 1。
2 和 3 两个规则可以推出一个有趣的结论:如果两个 Region 拥有的范围有重叠,只需比较两者的 version 即可确认两者之间的历史先后顺序,version 大的意味着更新,不存在相等的情况。
证明比较简单,由于范围只在 Split 和 Merge 的时候才会改变,而每一次的 Split 和 Merge 都会更新影响到的范围里 Region 的 version,并且更新到比原范围中的 version 更大,对于一段范围来说,不管它属于哪个 Region,它所在 Region 的 version 一定是严格单调递增的。
PD 使用了这个规则去判断范围重叠的不同 Region 的新旧。
每条 Proposal 都会在提出的时候带上 PeerFsm 的 Region epoch,在应用的时候检查该 Region epoch 的合法性,如果不合法就跳过。

最低0.47元/天 解锁文章
872





