更新时间:2021年10月21日16时53分 来源:传智教育 浏览次数:
TiKV 集群是 TiDB 数据库的分布式 KV 存储引擎,数据以 Region 为单位进行复制和管理,每个 Region 会有多个 Replica(副本),这些 Replica 会分布在不同的 TiKV 节点上,其中 Leader 负责读/写,Follower 负责同步 Leader 发来的 raft log。了解了这些信息后,请思考下面这些问题:
• 如何保证同一个 Region 的多个 Replica 分布在不同的节点上?更进一步,如果在一台机器上启动多个 TiKV 实例,会有什么问题?
• TiKV 集群进行跨机房部署用于容灾的时候,如何保证一个机房掉线,不会丢失 Raft Group 的多个 Replica?
• 添加一个节点进入 TiKV 集群之后,如何将集群中其他节点上的数据搬过来?
• 当一个节点掉线时,会出现什么问题?整个集群需要做什么事情?如果节点只是短暂掉线(重启服务),那么如何处理?如果节点是长时间掉线(磁盘故障,数据全部丢失),需要如何处理?
• 假设集群需要每个 Raft Group 有 N 个副本,那么对于单个 Raft Group 来说,Replica 数量可能会不够多(例如节点掉线,失去副本),也可能会过于多(例如掉线的节点又回复正常,自动加入集群)。那么如何调节 Replica 个数?
• 读/写都是通过 Leader 进行,如果 Leader 只集中在少量节点上,会对集群有什么影响?
• 并不是所有的 Region 都被频繁的访问,可能访问热点只在少数几个 Region,这个时候我们需要做什么?
• 集群在做负载均衡的时候,往往需要搬迁数据,这种数据的迁移会不会占用大量的网络带宽、磁盘 IO 以及 CPU?进而影响在线服务?
这些问题单独拿出可能都能找到简单的解决方案,但是混杂在一起,就不太好解决。有的问题貌似只需要考虑单个 Raft Group 内部的情况,比如根据副本数量是否足够多来决定是否需要添加副本。但是实际上这个副本添加在哪里,是需要考虑全局的信息。整个系统也是在动态变化,Region 分裂、节点加入、节点失效、访问热点变化等情况会不断发生,整个调度系统也需要在动态中不断向最优状态前进,如果没有一个掌握全局信息,可以对全局进行调度,并且可以配置的组件,就很难满足这些需求。因此我们需要一个中心节点,来对系统的整体状况进行把控和调整,所以有了 PD 这个模块。
调度的基本需求:
上面罗列了一大堆问题,我们先进行分类和整理。总体来看,问题有两大类:
1.作为一个分布式高可用存储系统,必须满足的需求,包括四种:
• 副本数量不能多也不能少
• 副本需要分布在不同的机器上
• 新加节点后,可以将其他节点上的副本迁移过来
• 节点下线后,需要将该节点的数据迁移走
2.作为一个良好的分布式系统,需要优化的地方,包括:
• 维持整个集群的 Leader 分布均匀
• 维持每个节点的储存容量均匀
• 维持访问热点分布均匀
• 控制 Balance 的速度,避免影响在线服务
• 管理节点状态,包括手动上线/下线节点,以及自动下线失效节点
满足第一类需求后,整个系统将具备多副本容错、动态扩容/缩容、容忍节点掉线以及自动错误恢复的功能。
满足第二类需求后,可以使得整体系统的负载更加均匀、且可以方便的管理。
为了满足这些需求,首先我们需要收集足够的信息,比如每个节点的状态、每个 Raft Group 的信息、业务访问操作的统计等;
其次需要设置一些策略,PD 根据这些信息以及调度的策略,制定出尽量满足前面所述需求的调度计划;最后需要一些基本的操作,来完成调度计划。