TiDB Operator 基于 StatefulSet 管理 Pod 的部署和扩缩容,但 StatefulSet
在某些 Pod 或者节点发生故障时不会自动创建新 Pod 来替换旧 Pod。为解决此问题,TiDB Operator 支持通过自动扩容 Pod 实现故障自动转移功能。
配置故障自动转移
故障自动转移功能在 TiDB Operator 中默认开启。
部署 TiDB Operator 时,可以在 charts/tidb-operator/values.yaml
文件中配置 TiDB 集群中 PD、TiKV、TiDB 和 TiFlash 组件故障转移的等待超时时间。示例如下:
controllerManager: ... # autoFailover is whether tidb-operator should auto failover when failure occurs autoFailover: true # pd failover period default(5m) pdFailoverPeriod: 5m # tikv failover period default(5m) tikvFailoverPeriod: 5m # tidb failover period default(5m) tidbFailoverPeriod: 5m # tiflash failover period default(5m) tiflashFailoverPeriod: 5m
其中,pdFailoverPeriod
、tikvFailoverPeriod
、tiflashFailoverPeriod
和 tidbFailoverPeriod
代表在确认实例故障后的等待超时时间,默认均为 5 分钟。超过这个时间后,TiDB Operator 就开始做故障自动转移。
另外,在配置 TiDB 集群时,可以通过 spec.${component}.maxFailoverCount
指定 TiDB Operator 在各组件故障自动转移时能扩容的 Pod 数量阈值,详情请参考 TiDB 组件配置文档。
注意
如果集群中没有足够的资源以供 TiDB Operator 扩容新 Pod,则扩容出的 Pod 会处于 Pending 状态。
实现原理
TiDB 集群包括 PD、TiKV、TiDB、TiFlash、TiCDC 和 Pump 六个组件。目前 TiCDC 和 Pump 并不支持故障自动转移,PD、TiKV、TiDB 和 TiFlash 的故障转移策略有所不同,本节将详细介绍这几种策略。
PD 故障转移策略
TiDB Operator 通过 pd/health
PD API 获取 PD members 健康状况,并记录到 TidbCluster CR 的 .status.pd.members
字段中。
以一个有 3 个 Pod 的 PD 集群为例,如果其中一个 Pod 不健康超过 5 分钟(pdFailoverPeriod
可配置),TiDB Operator 将自动进行以下操作:
- TiDB Operator 将此 Pod 信息记录到 TidbCluster CR 的
.status.pd.failureMembers
字段中。 - TiDB Operator 将此 Pod 下线:TiDB Operator 调用 PD API 将此 Pod 从 member 列表中删除,然后删掉 Pod 及其 PVC。
- StatefulSet controller 会重新创建此 Pod 并以新的 member 身份加入集群。
- 在计算 PD StatefulSet 的 Replicas 时,TiDB Operator 会将已经被删除过的
.status.pd.failureMembers
考虑在内,因此会扩容一个新的 Pod。此时将有 4 个 Pod 同时存在。
当原来集群中所有不健康的 Pod 都恢复正常时,TiDB Operator 会将新扩容的 Pod 自动缩容掉,恢复成原来的 Pod 数量。
注意
- TiDB Operator 会为每个 PD 集群最多扩容
spec.pd.maxFailoverCount
(默认3
) 个 Pod,超过这个阈值后不会再进行故障转移。 - 如果 PD 集群多数 member 已经不健康,导致 PD 集群不可用,TiDB Operator 不会为这个 PD 集群进行故障自动转移。
TiDB 故障转移策略
TiDB Operator 通过访问每个 TiDB Pod 的 /status
接口确认 Pod 健康状况,并记录到 TidbCluster CR 的 .status.tidb.members
字段中。
以一个有 3 个 Pod 的 TiDB 集群为例,如果一个 Pod 不健康超过 5 分钟(tidbFailoverPeriod
可配置),TiDB Operator 将自动进行以下操作:
- TiDB Operator 将此 Pod 信息记录到 TidbCluster CR 的
.status.tidb.failureMembers
字段中。 - 在计算 TiDB StatefulSet 的 Replicas 时,TiDB Operator 会将
.status.tidb.failureMembers
考虑在内,因此会扩容一个新的 Pod。此时会有 4 个 Pod 同时存在。
当原来集群中不健康的 Pod 恢复正常时,TiDB Operator 会将新扩容的 Pod 缩容掉,恢复成原来的 3 个 Pod。
注意
TiDB Operator 会为每个 TiDB 集群最多扩容 spec.tidb.maxFailoverCount
(默认 3
) 个 Pod,超过这个阈值后不会再进行故障转移。
TiKV 故障转移策略
TiDB Operator 通过访问 PD API 获取 TiKV store 健康状况,并记录到 TidbCluster CR 的 .status.tikv.stores
字段中。
以一个有 3 个 Pod 的 TiKV 集群为例,当一个 TiKV Pod 无法正常工作时,该 Pod 对应的 Store 状态会变为 Disconnected
。默认 30 分钟(可以通过 pd.config
中 [schedule]
部分的 max-store-down-time = "30m"
来修改)后会变成 Down
状态,然后 TiDB Operator 将自动进行以下操作:
- 在此基础上再等待 5 分钟(可以通过
tikvFailoverPeriod
配置),如果此 TiKV Pod 仍未恢复,TiDB Operator 会将此 Pod 信息记录到 TidbCluster CR 的.status.tikv.failureStores
字段中。 - 在计算 TiKV StatefulSet 的 Replicas 时,TiDB Operator 会将
.status.tikv.failureStores
考虑在内,因此会扩容一个新的 Pod。此时会有 4 个 Pod 同时存在。
当原来集群中不健康的 Pod 恢复正常时,考虑到缩容 Pod 需要迁移数据,可能会对集群性能有一定影响,TiDB Operator 并不会将新扩容的 Pod 缩容掉,而是继续保持 4 个 Pod。
注意
TiDB Operator 会为每个 TiKV 集群最多扩容 spec.tikv.maxFailoverCount
(默认 3
) 个 Pod,超过这个阈值后不会再进行故障转移。
如果所有异常的 TiKV Pod 都已经恢复,这时如果需要缩容新起的 Pod,请参考以下两种方法:
-
方法一:配置
spec.tikv.recoverFailover: true
(从 TiDB Operator v1.1.5 开始支持)。kubectl patch tc -n ${namespace} ${cluster_name} --type merge -p '{"spec":{"tikv":{"recoverFailover": true}}}'
TiDB Operator 在每次发生故障转移并恢复后都会自动缩容。
-
方法二:配置
spec.tikv.failover.recoverByUID: ${recover_uid}
。${recover_uid}
是本次故障恢复的 UID,可用用下面命令查看:kubectl get tc -n ${namespace} ${cluster_name} -ojsonpath='{.status.tikv.failoverUID}'
TiDB Operator 会根据
${recover_uid}
,将本次故障恢复新起的 TiKV Pod 自动缩容。
TiFlash 故障转移策略
TiDB Operator 通过访问 PD API 获取 TiFlash store 健康状况,并记录到 TidbCluster CR 的 .status.tiflash.stores
字段中。
以一个有 3 个 Pod 的 TiFlash 集群为例,当一个 TiFlash Pod 无法正常工作时,该 Pod 对应的 Store 状态会变为 Disconnected
。默认 30 分钟(可以通过 pd.config
中 [schedule]
部分的 max-store-down-time = "30m"
来修改)后会变成 Down
状态,然后 TiDB Operator 将自动进行以下操作:
- 在此基础上再等待 5 分钟(
tiflashFailoverPeriod
可配置),如果此 TiFlash Pod 仍未恢复,TiDB Operator 会将此 Pod 信息记录到 TidbCluster CR 的.status.tiflash.failureStores
字段中。 - 在计算 TiFlash StatefulSet 的 Replicas 时,TiDB Operator 会将
.status.tiflash.failureStores
考虑在内,因此会扩容一个新的 Pod。此时会有 4 个 Pod 同时存在。
当原来集群中不健康的 Pod 恢复正常时,考虑到缩容 Pod 需要迁移数据,可能会对集群性能有一定影响,TiDB Operator 并不会将新扩容的 Pod 缩容掉,而是继续保持 4 个 Pod。
注意
TiDB Operator 会为每个 TiFlash 集群最多扩容 spec.tiflash.maxFailoverCount
(默认 3
) 个 Pod,超过这个阈值后不会再进行故障转移。
如果所有异常的 TiFlash Pod 都已经恢复,这时如果需要缩容新起的 Pod,请参考以下两种方法:
-
方法一:配置
spec.tiflash.recoverFailover: true
(从 TiDB Operator v1.1.5 开始支持)。kubectl patch tc -n ${namespace} ${cluster_name} --type merge -p '{"spec":{"tiflash":{"recoverFailover": true}}}'
TiDB Operator 在每次发生故障转移并恢复后都会自动缩容。
-
方法二:配置
spec.tiflash.failover.recoverByUID: ${recover_uid}
。${recover_uid}
是本次故障恢复的 UID,可用用下面命令查看:kubectl get tc -n ${namespace} ${cluster_name} -ojsonpath='{.status.tiflash.failoverUID}'
TiDB Operator 会根据
${recover_uid}
,将本次故障恢复新起的 TiFlash Pod 自动缩容。
关闭故障自动转移
你可以在集群或组件级别关闭故障自动转移功能。
-
如需在集群级别关闭故障自动转移功能,在部署 TiDB Operator 时,请将
charts/tidb-operator/values.yaml
文件的controllerManager.autoFailover
字段值配置为false
。示例如下:controllerManager: ... # autoFailover is whether tidb-operator should auto failover when failure occurs autoFailover: false
-
如需在组件级别关闭故障自动转移功能,在创建 TiDB 集群时,请将 TidbCluster CR 中对应组件的
spec.${component}.maxFailoverCount
字段值配置为0
。