PD 源码分析 region 健康卫士的角色与功能

网友投稿 378 2024-03-15



PD 作为整个集群的大脑,时刻关注集群的状态,当集群出现非健康状态时产生新的 operator(调度单元) 指导 tikv 进行修复。针对集群的基本逻辑单元 region, PD 也有一个专门的协程负责检查并生成对应的 operator 指导 tikv 进行自愈。

PD 源码分析 region 健康卫士的角色与功能

PD 中负责这部分逻辑的在 checkController 中, 其主要工作为,检查每个 region 的状态,必要时生成 operator. 如

当有 region 的副本(peer) 处于非正常状态时,生成 operator 加速其变成正常状态

当 region 太大时,触发分裂。

当 Region 不符合当前的副本定义规则(placementrule) 时,生成对应调度

当前 region 过小时,尝试合并。

Check 执行主流程

其主流程在 coordinator 中展开,以轮训地方式定期检测所有 region 是否需要生成调度。相关代码模块参考

ParalRegions

paralRegions 默认每隔 10ms 顺序扫 region, 检查当前批次 region 是否需要生成调度。

间隔时间 10ms 可通过配置项 patrol-region-interval 进行调整。

每一轮巡检操作如下:

Unsafe recover 检测

如果当前 cluster 处于 recovery 状态,跳过直到 unsafe recovery 完成

checkPriorityRegions

Priority region 主要来自于 checkRegion 中发现副本缺失时的 region

checkSuspectRegions

Suspect region 主要来自于 placement-rule 发生更新后,会将相关 region 放进来检查

checkWaitingRegions

主要出现在 check region 中发现副本缺失,生成了 operator, 但是发现当前已经达到 storelimit 门槛。

扫当前集群 region 信息

从上一次 key 往后获取 128(const) 个 region

如果 regions 个数为 0,key 重置到起点 nil, 下一次重头扫

顺序对每一个 region 进行检查,看其是否有必要生成新的 operator

若已经有 pending 中的 operator, 则不需要

CheckRegion 检查当前 region 是否需要新的 operator. 具体流程见下文。

将 key 设置为当前 region 的 end-key

检查 CheckRegion 生成的 operator,检查步骤如下

没有 operator, 继续下一个 region

超过 storeLimit 限制,将当前 region 加入到 waitingRegion, 在下一轮 iv (checkWaitingRegions) 里处理

当前 operator 可以进行

加入到 operatorController 中(opController.AddWaitingOperator)

当前 region 从 waitingRegion 中删除

当前 region 从 suspectRegion 中删除

更新统计信息

更新 region label 相关统计信息

如果正好扫完了所有 region(len(key)=0), 上报处理完整个集群的使用时间。

CheckRegion

CheckRegion 主要用于检查当前 region 是否需要新的 operator,当前版本检查流程如下(其中 红点为诊断需要关注的地方):

jointStateChecker 副本中间状态安全卫士

如果发现当前 region 有副本(peer)处于中间状态,生成对应 operator 将其切换至正常状态。详细过程如下:

IsPaused, return

检查 region 状态

Peers 都不在 joint state,return

jointState 状态定义为:当前存在 peer 为 learner<-> voter 切换的中间状态,或新节点刚加入但还在成为 learner , voter 过程中。

创建 LeaveJointStateOperator

operator builder 检查 region 基本信息,若存在异常,return

Peers 离开了 joint state,return

创建 operator ,return

该 operator 优先级设置为最高

ScheduleDisabled

如果当前 region 被标记了 scheduleDisabled 停止调度 label, 返回 nil, 不需要新 operator

SplitChecker

检查当前 region 是否过大,如果过大,则生成对应 operator 指导进行分裂。详细过程如下:

IsPaused, return

准备 split-key

Label 中当前 region 所在返回内的所有 key

如果上述 key 个数为 0 且存在 placementrule, 则获取当前 placement rule 对应到本 region 的所有 key.

splitChecker 根据 label 和 placementrule 检查是否需要 split

Any Label 的 range 边界存在在当前 region 中,需要 split

Any plancementrule 的 range 边界在当前 region 中,需要 split

ruleChecker(Placementrule 启用时副本检测)

Plancement rule 启用时,检查当前 region 在该 plancementrule 下是否需要生成调度。考虑其复杂度,后续会单独给出详细源码分析文章。

Palacementrule 不启用时副本检测

Learnerchecker 会将当前系统中所有 learner 变成 voter.

ReplicaCHecker 会将缺失副本补全

补副本类的 operator 未到达上限,返回该 operator

补副本类的 operator 已经到达上限,对应 region 加入 regionWaitingList

Mergechecker

如果启用了 merge-checker, 则开始 merge checker, 如果发现当前 region 过小(比如大量的数据删除导致空 region),则生成对应的 operator 进行合并。详细过程如下:

检查当前 merge 类的 operator 是否已经到达上限,若是返回 nil

如果系统刚启动或者 merge-checker 新添加,过一段时间才开始工作,返回 nil

更新当前 splitCache 里面的 TTL

检查当前 region 是否符合 merge 条件

如果 splitCache 里面有当前 region, 即当前 region 刚 split 过,不做merge,return nil

如果 region approximate size 为 0,即 PD 还未收集到该 region 的信息,不做 merge, 返回 nil

检查 region 的 size 和 key 个数,如果比较大,不做 merge, 返回 nil

如果当前 region 不处于一个健康状态,如有 pending peer,或 down peer, 不做 merge, 返回 nil

如果当前 region 有副本缺失,不做 merge, 返回 nil

如果当前 region 为热点region,返回 nil

选取该 region 临近的两个 region prev & next

优先检查 next 是否符合 merge 到当前 region 的条件

如果 next 不符合,配置允许向前 merge, 检查 prev 是否符合条件

再次检查 target region 的 size 和 key 个数是否过大

检查 merge 后的新 region 是否会很快被分裂

合并后的 size 是否会过大

合并后的 keys 是否会过多

创建 merge operator

更新统计信息

返回 merge operators

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:PCTP考试学习笔记之二 TiDB 数据库schema设计要点
下一篇:PD 节点恢复的挑战 当一个也不剩
相关文章