TiDB调度管理

1 调度的意义

	1. 如何保证同一个 Region 的多个 Replica 分布在不同的节点上
	2. TiKV 集群进行跨机房部署用于容灾的时候,如何保证一个机房掉线,不会丢失 Raft Group 的多个 Replica
	3. 添加一个节点进入 TiKV 集群之后,如何将集群中其他节点上的数据搬过来
	4. 当一个节点掉线时,会出现什么问题?整个集群需要做什么事情?如果节点只是短暂掉线(重启服务),那么如何处理?如果节点是长时间掉线(磁盘故障,数据全部丢失),需要如何处理?
	5. 假设集群需要每个 Raft Group 有 N 个副本,那么对于单个 Raft Group 来说,Replica 数量可能会不够多(例如节点掉线,失去副本),也可能会 过于多(例如掉线的节点又回复正常,自动加入集群)。那么如何调节 Replica 个数?
	6. 读/写都是通过 Leader 进行,如果 Leader 只集中在少量节点上,会对集群有什么影响?
	7. 并不是所有的 Region 都被频繁的访问,可能访问热点只在少数几个 Region,这个时候我们需要做什么?
	8. 集群在做负载均衡的时候,往往需要搬迁数据,这种数据的迁移会不会占用大量的网络带宽、磁盘 IO 以及 CPU?进而影响在线服务?

基于以上问题,衍生了PD模块,即调度管理模块(Placement Driver)

2 PD模块设计关键点

围绕上述问题,有几个核心解决点如下

  1. 副本数量要合理
  2. 副本分布要均匀
  3. 新加节点后,可以将其他节点上的副本迁移过来
  4. 下线节点后,需要将该节点的数据进行迁移走

因此整体的优化原则:

  1. 维持整个集群的 Leader 分布均匀
  2. 维持每个节点的储存容量均匀
  3. 维持访问热点分布均匀
  4. 控制 Balance 的速度,避免影响在线服务
  5. 管理节点状态,包括手动上线/下线节点,以及自动下线失效节点

3 调度基本操作

  1. 增加一个Replica
  2. 删除一个Replica
  3. 变更Replica之间的leader

4 调度信息收集

4.1 TiKV节点状态

每个TiKV节点会通过心跳包定期向PD汇报节点整体信息,信息指标包括

  1. 总磁盘容量
  2. 可用磁盘容量
  3. 承载的Region数量
  4. 数据写入速度
  5. 是否过载

4.2 Region状态

每个 Raft Group 的 Leader 和 PD 之间存在心跳包,也是通过心跳包进行信息汇报,信息指标如下:

  1. Leader的位置
  2. Followers 的位置
  3. 掉线 Replica 的个数
  4. 数据写入/读取的速度

心跳包会设置超时时间,当超过一定时间无法接到心跳包时,PD也会做对应的下线转移处理

5 调度实现

PD 不断的通过 Store 或者 Leader 的心跳包收集信息,获得整个集群的详细数据,并且根据这些信息以及调度策略生成调度操作序列,每次收到 Region Leader 发来的心跳包时,PD 都会检查是否有对这个 Region 待进行的操作,通过心跳包的回复消息,将需要进行的操作返回给 Region Leader,并在后面的心跳包中监测执行结果。注意这里的操作只是给 Region Leader 的建议,并不保证一定能得到执行,具体是否会执行以及什么时候执行,由 Region Leader 自己根据当前自身状态来定。