TiDB Scheduler 扩展调度器
TiDB 集群包括 PD,TiKV 以及 TiDB 三个核心组件,每个组件又是由多个节点组成,PD 是一个 Raft 集群,TiKV 是一个多 Raft Group 集群,并且这两个组件都是有状态的。默认 Kubernetes 的调度器的调度规则无法满足 TiDB 集群的高可用调度需求,需要扩展 Kubernetes 的调度规则。
目前,可通过修改 TidbCluster 的 来按照特定的维度进行调度,比如:
或者修改 tidb-cluster chart 的 values.yaml
:
上述配置按照节点(默认值)维度进行调度,若要按照其他维度调度,比如: pingcap.com/ha-topology-key: zone
,表示按照 zone 调度,还需给各节点打如下标签:
不同节点可有不同的标签,也可有相同的标签,如果某一个节点没有打该标签,则调度器不会调度 pod 到该节点。
调度规则一:确保每个节点上调度的 PD 实例个数小于 Replicas / 2
。例如:
调度规则二:如果 Kubernetes 节点数小于 3 个(Kubernetes 集群节点数小于 3 个是无法实现 TiKV 高可用的),则可以任意调度;否则,每个节点上可调度的 TiKV 个数的计算公式为:ceil(Replicas/3)
。例如:
TiKV 集群规模(Replicas) | 每个节点最多可调度的 TiKV 实例数量 | 最佳调度分布 |
---|---|---|
3 | 1 | 1,1,1 |
4 | 2 | 1,1,2 |
5 | 2 | 1,2,2 |
6 | 2 | 2,2,2 |
7 | 3 | 2,2,3 |
8 | 3 | 2,3,3 |
… |
调度规则三:在 TiDB 实例滚动更新的时候,尽量将其调度回原来的节点。
这样实现了稳定调度,对于手动将 Node IP + NodePort 挂载在 LB 后端的场景比较有帮助,避免升级集群后 Node IP 发生变更时需要重新调整 LB,这样可以减少滚动更新时对集群的影响。
工作原理
TiDB Scheduler 通过实现 Kubernetes 调度器扩展()来添加自定义调度规则。
TiDB Scheduler 组件部署为一个或者多个 Pod,但同时只有一个 Pod 在工作。Pod 内部有两个 Container,一个 Container 是原生的 ;另外一个 Container 是 tidb-scheduler
,实现为一个 Kubernetes scheduler extender。
TiDB Operator 创建的 PD、TiDB、TiKV Pod 的 .spec.schedulerName
属性会被设置为 tidb-scheduler
,即都用 TiDB Scheduler 自定义调度器来调度。如果是测试集群,并且不要求高可用,可以将 .spec.schedulerName
改成 default-scheduler
使用 Kubernetes 内置的调度器。
一个 Pod 的调度流程是这样的:
- 在这之后,
kube-scheduler
会发请求到tidb-scheduler
服务,tidb-scheduler
会通过一些自定义的调度规则(见上述介绍)对发送过来的节点进行过滤,最终将剩余可调度的节点返回给 ; - 最终由
kube-scheduler
决定最终调度的节点。