在 Kubernetes 中配置 TiDB 集群
本文档介绍了如何配置生产可用的 TiDB 集群。涵盖以下内容:
资源配置
部署前需要根据实际情况和需求,为 TiDB 集群各个组件配置资源,其中 PD、TiKV、TiDB 是 TiDB 集群的核心服务组件,在生产环境下它们的资源配置还需要按组件要求指定,具体参考:资源配置推荐。
为了保证 TiDB 集群的组件在 Kubernetes 中合理的调度和稳定的运行,建议为其设置 Guaranteed 级别的 QoS,通过在配置资源时让 limits 等于 requests 来实现, 具体参考:配置 QoS。
如果使用 NUMA 架构的 CPU,为了获得更好的性能,需要在节点上开启 Static
的 CPU 管理策略。为了 TiDB 集群组件能独占相应的 CPU 资源,除了为其设置上述 Guaranteed 级别的 QoS 外,还需要保证 CPU 的配额必须是大于或等于 1 的整数。具体参考: CPU 管理策略。
部署配置
通过配置 TidbCluster
CR 来配置 TiDB 集群。参考 TidbCluster 示例和 API 文档(示例和 API 文档请切换到当前使用的 TiDB Operator 版本)完成 TidbCluster CR(Custom Resource)。
集群名称
通过更改 TiDBCuster
CR 中的 metadata.name
来配置集群名称。
版本
正常情况下,集群内的各组件应该使用相同版本,所以一般建议配置 spec.<pd/tidb/tikv/pump/tiflash/ticdc>.baseImage
+ spec.version
即可。如果需要为不同的组件配置不同的版本,则可以配置 spec.<pd/tidb/tikv/pump/tiflash/ticdc>.version
。
相关参数的格式如下:
spec.version
,格式为imageTag
,例如v7.5.3
spec.<pd/tidb/tikv/pump/tiflash/ticdc>.baseImage
,格式为imageName
,例如pingcap/tidb
spec.<pd/tidb/tikv/pump/tiflash/ticdc>.version
,格式为imageTag
,例如v7.5.3
推荐配置
configUpdateStrategy
spec.configUpdateStrategy
字段默认值为 InPlace
,表示当你修改某个组件的 config
后,需要手动触发滚动更新后才会应用新的配置。
建议设置 spec.configUpdateStrategy: RollingUpdate
,开启配置自动更新特性,在某个组件的 config
更新时,自动对组件执行滚动更新,将修改后的配置应用到集群中。
enableDynamicConfiguration
建议通过设置 spec.enableDynamicConfiguration: true
配置 TiKV 的 --advertise-status-addr
启动参数。
版本支持:TiDB v4.0.1 及更高版本。
pvReclaimPolicy
建议设置 spec.pvReclaimPolicy: Retain
,确保 PVC 被删除后 PV 仍然保留,保证数据安全。
mountClusterClientSecret
PD 和 TiKV 支持配置 mountClusterClientSecret
。如果开启了集群组件间 TLS 支持,建议配置 spec.pd.mountClusterClientSecret: true
和 spec.tikv.mountClusterClientSecret: true
,这样 TiDB Operator 会自动将 ${cluster_name}-cluster-client-secret
证书挂载到 PD 和 TiKV 容器,方便使用 pd-ctl
和 tikv-ctl
。
startScriptVersion
你可以配置 spec.startScriptVersion
字段,用于选择各个组件的不同版本的启动脚本。
目前支持的启动脚本的版本如下:
v1
:默认值,最初版本的启动脚本。v2
:为了优化各个组件的启动脚本,并且确保在升级 TiDB Operator 后不会导致集群滚动重启,自 TiDB Operator v1.4.0 起新增v2
版本。相比于v1
,v2
有以下优化:- 使用
dig
命令替换nslookup
命令来解析 DNS。 - 所有组件都支持诊断模式。
- 使用
新部署的集群建议配置 spec.startScriptVersion
为最新的版本,即 v2
。
存储
存储类型
如果需要设置存储类型,可以修改 ${cluster_name}/tidb-cluster.yaml
中各组件的 storageClassName
字段。关于 Kubernetes 集群支持哪些存储类型,请联系系统管理员确定。
另外,TiDB 集群不同组件对磁盘的要求不一样,所以部署集群前,要根据当前 Kubernetes 集群支持的存储类型以及使用场景,参考存储配置文档为 TiDB 集群各组件选择合适的存储类型。
多盘挂载
TiDB Operator 支持为 PD、TiDB、TiKV、TiCDC 挂载多块 PV,可以用于不同用途的数据写入。
每个组件都可以配置 storageVolumes
字段,用于描述用户自定义的多个 PV。
相关字段的含义如下:
storageVolume.name
:PV 的名称。storageVolume.storageClassName
:PV 使用哪一个 StorageClass。如果不配置,会使用 spec.pd/tidb/tikv/ticdc.storageClassName。storageVolume.storageSize
:申请 PV 存储容量的大小。storageVolume.mountPath
:将 PV 挂载到容器的哪个目录。
例子:
- TiKV
- TiDB
- PD
- TiCDC
为 TiKV 挂载多块 PV:
tikv:
...
config: |
[rocksdb]
wal-dir = "/data_sbi/tikv/wal"
[titan]
dirname = "/data_sbj/titan/data"
storageVolumes:
- name: wal
storageSize: "2Gi"
mountPath: "/data_sbi/tikv/wal"
- name: titan
storageSize: "2Gi"
mountPath: "/data_sbj/titan/data"
为 TiDB 挂载多块 PV:
tidb:
config: |
path = "/tidb/data"
[log.file]
filename = "/tidb/log/tidb.log"
storageVolumes:
- name: data
storageSize: "2Gi"
mountPath: "/tidb/data"
- name: log
storageSize: "2Gi"
mountPath: "/tidb/log"
为 PD 挂载多块 PV:
pd:
config: |
data-dir = "/pd/data"
[log.file]
filename = "/pd/log/pd.log"
storageVolumes:
- name: data
storageSize: "10Gi"
mountPath: "/pd/data"
- name: log
storageSize: "10Gi"
mountPath: "/pd/log"
为 TiCDC 挂载多块 PV:
ticdc:
...
config:
dataDir: /ticdc/data
logFile: /ticdc/log/cdc.log
storageVolumes:
- name: data
storageSize: "10Gi"
storageClassName: local-storage
mountPath: "/ticdc/data"
- name: log
storageSize: "10Gi"
storageClassName: local-storage
mountPath: "/ticdc/log"
HostNetwork
PD、TiKV、TiDB、TiFlash、TiProxy、TiCDC 及 Pump 支持配置 Pod 使用宿主机上的网络命名空间 HostNetwork
。可通过配置 spec.hostNetwork: true
为所有受支持的组件开启,或通过为特定组件配置 hostNetwork: true
为单个或多个组件开启。
Discovery
TiDB Operator 会为每一个 TiDB 集群启动一个 Discovery 服务。Discovery 服务会为每个 PD Pod 返回相应的启动参数,来辅助 PD 集群启动。你可以通过 spec.discovery
配置 Discovery 服务的资源,详见容器资源管理。
spec.discovery
配置示例:
spec:
discovery:
limits:
cpu: "0.2"
requests:
cpu: "0.2"
...
集群拓扑
PD/TiKV/TiDB
默认示例的集群拓扑是:3 个 PD Pod,3 个 TiKV Pod,2 个 TiDB Pod。在该部署拓扑下根据数据高可用原则,TiDB Operator 扩展调度器要求 Kubernetes 集群中至少有 3 个节点。可以修改 replicas
配置来更改每个组件的 Pod 数量。
部署 TiProxy
部署方法与 PD 一致。此外,还需要修改 spec.tiproxy
来手动指定 TiProxy 组件的数量。
tiproxy:
baseImage: pingcap/tiproxy
replicas: 3
config:
部署 TiProxy 时,还需要给 TiDB 配置额外参数,详细的配置步骤见为已有 TiDB 集群部署负载均衡 TiProxy。
部署 TiFlash
如果要在集群中开启 TiFlash,需要在 ${cluster_name}/tidb-cluster.yaml
文件中配置 spec.pd.config.replication.enable-placement-rules: true
,并配置 spec.tiflash
:
pd:
config: |
...
[replication]
enable-placement-rules = true
tiflash:
baseImage: pingcap/tiflash
maxFailoverCount: 0
replicas: 1
storageClaims:
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
TiFlash 支持挂载多个 PV,如果要为 TiFlash 配置多个 PV,可以在 tiflash.storageClaims
下面配置多项,每一项可以分别配置 storage request
和 storageClassName
,例如:
tiflash:
baseImage: pingcap/tiflash
maxFailoverCount: 0
replicas: 1
storageClaims:
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
所有 PV 按照配置先后顺序分别挂载到容器内的 /data0
、/data1
等目录。TiFlash 有 4 个日志文件,其中 Proxy 日志打印到容器标准输出,另外 3 个日志存储在硬盘中,默认存储在 /data0
目录下,分别为 /data0/logs/flash_cluster_manager.log
、/data0/logs/error.log
、/data0/logs/server.log
,如果要修改日志存储路径,可以参考配置 TiFlash 配置参数进行修改。
部署 TiCDC
如果要在集群中开启 TiCDC,需要在 ${cluster_name}/tidb-cluster.yaml
文件中配置 spec.ticdc
:
ticdc:
baseImage: pingcap/ticdc
replicas: 3
config:
logLevel: info
配置 TiDB 组件
本节介绍如何配置 TiDB/TiKV/PD/TiProxy/TiFlash/TiCDC 的配置选项。
配置 TiDB 配置参数
你可以通过 TidbCluster CR 的 spec.tidb.config
来配置 TiDB 配置参数。
spec:
tidb:
config: |
split-table = true
oom-action = "log"
获取所有可以配置的 TiDB 配置参数,请参考 TiDB 配置文档。
配置 TiKV 配置参数
你可以通过 TidbCluster CR 的 spec.tikv.config
来配置 TiKV 配置参数。
spec:
tikv:
config: |
[storage]
[storage.block-cache]
capacity = "16GB"
获取所有可以配置的 TiKV 配置参数,请参考 TiKV 配置文档
配置 PD 配置参数
你可以通过 TidbCluster CR 的 spec.pd.config
来配置 PD 配置参数。
spec:
pd:
config: |
lease = 3
enable-prevote = true
获取所有可以配置的 PD 配置参数,请参考 PD 配置文档
配置 TiProxy 配置参数
你可以通过 TidbCluster CR 的 spec.tiproxy.config
来配置 TiProxy 配置参数。
spec:
tiproxy:
config: |
[log]
level = "info"
获取所有可以配置的 TiProxy 配置参数,请参考 TiProxy 配置文档。
配置 TiFlash 配置参数
你可以通过 TidbCluster CR 的 spec.tiflash.config
来配置 TiFlash 配置参数。
spec:
tiflash:
config:
config: |
[flash]
[flash.flash_cluster]
log = "/data0/logs/flash_cluster_manager.log"
[logger]
count = 10
level = "information"
errorlog = "/data0/logs/error.log"
log = "/data0/logs/server.log"
获取所有可以配置的 TiFlash 配置参数,请参考 TiFlash 配置文档
配置 TiCDC 启动参数
你可以通过 TidbCluster CR 的 spec.ticdc.config
来配置 TiCDC 启动参数。
对于 TiDB Operator v1.2.0-rc.2 及之后版本,请使用 TOML 格式配置:
spec:
ticdc:
config: |
gc-ttl = 86400
log-level = "info"
对于 TiDB Operator v1.2.0-rc.2 之前版本,请使用 YAML 格式配置:
spec:
ticdc:
config:
timezone: UTC
gcTTL: 86400
logLevel: info
获取所有可以配置的 TiCDC 启动参数,请参考 TiCDC 启动参数文档。
配置 PD、TiDB、TiKV、TiFlash 故障自动转移阈值
故障自动转移功能在 TiDB Operator 中默认开启。当 PD、TiDB、TiKV、TiFlash 这些组件的 Pod 或者其所在节点发生故障时,TiDB Operator 会触发故障自动转移,通过扩容相应组件补齐 Pod 副本数。
为避免故障自动转移功能创建太多 Pod,可以为每个组件配置故障自动转移时能扩容的 Pod 数量阈值,默认为 3
。如果配置为 0
,代表关闭这个组件的故障自动转移功能。配置示例如下:
pd:
maxFailoverCount: 3
tidb:
maxFailoverCount: 3
tikv:
maxFailoverCount: 3
tiflash:
maxFailoverCount: 3
配置 TiDB 平滑升级
滚动更新 TiDB 集群的过程中,在停止 TiDB Pod 之前,Kubernetes 会向 TiDB server 进程发送一个 TERM
信号。在收到 TERM
信号后,TiDB server 会尝试等待所有的连接关闭,不过 15 秒后会强制关闭所有连接并退出进程。
通过配置下面两个属性来实现平滑升级 TiDB 集群:
spec.tidb.terminationGracePeriodSeconds
:滚动更新的时候,删除旧的 TiDB Pod 最多容忍的时间,即过了这个时间,TiDB Pod 会被强制删除;spec.tidb.lifecycle
:设置 TiDB Pod 的preStop
Hook,在 TiDB server 停止之前执行的操作。
spec:
tidb:
...
terminationGracePeriodSeconds: 60
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- "sleep 10 && kill -QUIT 1"
上述 YAML 文件中:
- 设置了删除 TiDB Pod 的最多容忍时间为 60 秒,如果 60 秒之内客户端仍然没有关闭连接的话,那么这些连接将会强制关闭。这个时间可根据需要进行调整;
- 设置
preStop
Hook 为sleep 10 && kill -QUIT 1
,这里 Pid 1 为 TiDB Pod 内 TiDB server 进程的 Pid。TiDB server 进程收到这个信号之后,会等待所有连接被客户端关闭之后才会退出。
Kubernetes 在删除 TiDB Pod 的同时,也会把该 TiDB 节点从 Service 的 Endpoints 中移除。这样就可以保证新的连接不会连接到该 TiDB 节点,但是由于此过程是异步的,所以可以在发送 Kill 信号之前 sleep 几秒钟,确保该 TiDB 节点从 Endpoints 中去掉。
配置 TiKV 平滑升级
TiKV 升级过程中,在重启 TiKV Pod 之前,TiDB Operator 会先驱逐 TiKV Pod 上的所有 Region leader。只有当驱逐完成(即 TiKV Pod 上的 Region leader 个数为 0)或者驱逐超时(默认 1500 分钟)后,TiKV Pod 才会重启。如果集群的 TiKV 副本数小于 2,TiDB Operator 不再等待超时,直接触发强制升级。
如果驱逐 Region leader 超时,重启 TiKV Pod 会导致部分请求失败或者延时增加。要避免此问题,你可以将超时时间 spec.tikv.evictLeaderTimeout
(默认 1500 分钟)配置为一个更大的值,例如:
spec:
tikv:
evictLeaderTimeout: 10000m
配置 TiCDC 平滑升级
TiCDC 升级过程中,在重启 TiCDC Pod 之前,TiDB Operator 会先转移 TiCDC Pod 上的所有的同步负载。只有当转移完成或者转移超时(默认 10 分钟)后,TiCDC Pod 才会重启。如果集群的 TiCDC 实例数小于 2,TiDB Operator 不再等待超时,直接触发强制升级。
如果转移超时,重启 TiCDC Pod 会导致同步延时增加。要避免此问题,你可以将超时时间 spec.ticdc.gracefulShutdownTimeout
(默认 10 分钟)配置为一个更大的值,例如:
spec:
ticdc:
gracefulShutdownTimeout: 100m
配置 TiDB 慢查询日志持久卷
默认配置下,TiDB Operator 会新建名称为 slowlog
的 EmptyDir
卷来存储慢查询日志,slowlog
卷默认挂载到 /var/log/tidb
,慢查询日志通过 sidecar 容器打印到标准输出。
如果想使用单独的持久卷来存储慢查询日志,可以通过配置 spec.tidb.slowLogVolumeName
单独指定存储慢查询日志的持久卷名称,并在 spec.tidb.storageVolumes
或 spec.tidb.additionalVolumes
配置持久卷信息。下面分别演示使用 spec.tidb.storageVolumes
和 spec.tidb.additionalVolumes
配置持久卷。
spec.tidb.storageVolumes 配置
按照如下示例配置 TidbCluster
CR,TiDB Operator 将使用持久卷 ${volumeName}
存储慢查询日志,日志文件路径为:${mountPath}/${volumeName}
。spec.tidb.storageVolumes
字段的具体配置方式可参考多盘挂载。
tidb:
...
separateSlowLog: true # 可省略
slowLogVolumeName: ${volumeName}
storageVolumes:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
storageClassName: ${storageClass}
storageSize: "1Gi"
mountPath: ${mountPath}
spec.tidb.additionalVolumes 配置
下面以 NFS 为例配置 spec.tidb.additionalVolumes
。TiDB Operator 将使用持久卷 ${volumeName}
存储慢查询日志,日志文件路径为:${mountPath}/${volumeName}
。具体支持的持久卷类型可参考 Persistent Volumes。
tidb:
...
separateSlowLog: true # 可省略
slowLogVolumeName: ${volumeName}
additionalVolumes:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
nfs:
server: 192.168.0.2
path: /nfs
additionalVolumeMounts:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
mountPath: ${mountPath}
配置 TiDB 服务
需要配置 spec.tidb.service
,TiDB Operator 才会为 TiDB 创建 Service。Service 可以根据场景配置不同的类型,比如 ClusterIP
、NodePort
、LoadBalancer
等。
通用配置
不用类型的 Service 有着部分通用的配置,包括:
spec.tidb.service.annotations
:添加到 Service 资源的 Annotation。spec.tidb.service.labels
:添加到 Service 资源的 Labels。
ClusterIP
ClusterIP
是通过集群的内部 IP 暴露服务,选择该类型的服务时,只能在集群内部访问,使用 ClusterIP 或者 Service 域名(${cluster_name}-tidb.${namespace}
)访问。
spec:
tidb:
service:
type: ClusterIP
NodePort
在没有 LoadBalancer 时,可选择通过 NodePort 暴露。NodePort 是通过节点的 IP 和静态端口暴露服务。通过请求 NodeIP + NodePort
,可以从集群的外部访问一个 NodePort 服务。
spec:
tidb:
service:
type: NodePort
# externalTrafficPolicy: Local
NodePort 有两种模式:
externalTrafficPolicy=Cluster
:集群所有的机器都会给 TiDB 分配 NodePort 端口,此为默认值使用
Cluster
模式时,可以通过任意一台机器的 IP 加 NodePort 访问 TiDB 服务,如果该机器上没有 TiDB Pod,则相应请求会转发到有 TiDB Pod 的机器上。externalTrafficPolicy=Local
:只有运行 TiDB 的机器会分配 NodePort 端口,用于访问本地的 TiDB 实例
LoadBalancer
若运行在有 LoadBalancer 的环境,比如 Google Cloud、AWS 平台,建议使用云平台的 LoadBalancer 特性。
spec:
tidb:
service:
annotations:
cloud.google.com/load-balancer-type: "Internal"
externalTrafficPolicy: Local
type: LoadBalancer
访问 Kubernetes Service 文档,了解更多 Service 特性以及云平台 Load Balancer 支持。
若指定了 TiProxy,也会自动创建 tiproxy-api
和 tiproxy-sql
服务供使用。
IPv6 支持
TiDB 自 v6.5.1 起支持使用 IPv6 地址进行所有网络连接。如果你使用 v1.4.3 或以上版本的 TiDB Operator 部署 TiDB,你可以通过配置 spec.preferIPv6
为 true
来部署监听 IPv6 地址的 TiDB 集群。
spec:
preferIPv6: true
# ...
高可用配置
TiDB 是分布式数据库,它的高可用需要做到在任一个物理拓扑节点发生故障时,不仅服务不受影响,还要保证数据也是完整和可用。下面分别具体说明这两种高可用的配置。
TiDB 服务高可用
通过 nodeSelector 调度实例
通过各组件配置的 nodeSelector
字段,可以约束组件的实例只能调度到特定的节点上。关于 nodeSelector
的更多说明,请参阅 nodeSelector。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
# ...
spec:
pd:
nodeSelector:
node-role.kubernetes.io/pd: true
# ...
tikv:
nodeSelector:
node-role.kubernetes.io/tikv: true
# ...
tidb:
nodeSelector:
node-role.kubernetes.io/tidb: true
# ...
通过 tolerations 调度实例
通过各组件配置的 tolerations
字段,可以允许组件的实例能够调度到带有与之匹配的污点 (Taint) 的节点上。关于污点与容忍度的更多说明,请参阅 Taints and Tolerations。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
# ...
spec:
pd:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: pd
# ...
tikv:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: tikv
# ...
tidb:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: tidb
# ...
通过 affinity 调度实例
配置 PodAntiAffinity
能尽量避免同一组件的不同实例部署到同一个物理拓扑节点上,从而达到高可用的目的。关于 Affinity 的使用说明,请参阅 Affinity & AntiAffinity。
下面是一个典型的高可用设置例子:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
# this term works when the nodes have the label named region
- weight: 10
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "region"
namespaces:
- ${namespace}
# this term works when the nodes have the label named zone
- weight: 20
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "zone"
namespaces:
- ${namespace}
# this term works when the nodes have the label named rack
- weight: 40
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "rack"
namespaces:
- ${namespace}
# this term works when the nodes have the label named kubernetes.io/hostname
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "kubernetes.io/hostname"
namespaces:
- ${namespace}
通过 topologySpreadConstraints 实现 Pod 均匀分布
配置 topologySpreadConstraints
可以实现同一组件的不同实例在拓扑上的均匀分布。具体配置方法请参阅 Pod Topology Spread Constraints。
如需使用 topologySpreadConstraints
,需要满足以下条件:
- Kubernetes 集群使用
default-scheduler
,而不是tidb-scheduler
。详情可以参考 tidb-scheduler 与 default-scheduler。 - 如果 Kubernetes 版本在 v1.16 或 v1.21 之间,需要开启
EvenPodsSpread
feature gate。如果 Kubernetes 版本低于 v1.16 或集群未开启EvenPodsSpread
feature gate,topologySpreadConstraints
的配置将不会生效。如果 Kubernetes 版本为 v1.22 或更高版本,可忽略该条件。
topologySpreadConstraints
可以设置在整个集群级别 (spec.topologySpreadConstraints
) 来配置所有组件或者设置在组件级别 (例如 spec.tidb.topologySpreadConstraints
) 来配置特定的组件。
以下是一个配置示例:
topologySpreadConstraints:
- topologyKey: kubernetes.io/hostname
- topologyKey: topology.kubernetes.io/zone
该配置能让同一组件的不同实例均匀分布在不同 zone 和节点上。
当前 topologySpreadConstraints
仅支持 topologyKey
配置。在 Pod spec 中,上述示例配置会自动展开成如下配置:
topologySpreadConstraints:
- topologyKey: kubernetes.io/hostname
maxSkew: 1
whenUnsatisfiable: DoNotSchedule
labelSelector: <object>
- topologyKey: topology.kubernetes.io/zone
maxSkew: 1
whenUnsatisfiable: DoNotSchedule
labelSelector: <object>
数据的高可用
在开始数据高可用配置前,首先请阅读集群拓扑信息配置。该文档描述了 TiDB 集群数据高可用的实现原理。
在 Kubernetes 上支持数据高可用的功能,需要如下操作:
为 PD 设置拓扑位置 Label 集合
用 Kubernetes 集群 Node 节点上描述拓扑位置的 Label 集合替换
pd.config
配置项中里的location-labels
信息。为 TiKV 节点设置所在的 Node 节点的拓扑信息
TiDB Operator 会自动为 TiKV 获取其所在 Node 节点的拓扑信息,并调用 PD 接口将这些信息设置为 TiKV 的 store labels 信息,这样 TiDB 集群就能基于这些信息来调度数据副本。
如果当前 Kubernetes 集群的 Node 节点没有表示拓扑位置的 Label,或者已有的拓扑 Label 名字中带有
/
,可以通过下面的命令手动给 Node 增加标签:kubectl label node ${node_name} region=${region_name} zone=${zone_name} rack=${rack_name} kubernetes.io/hostname=${host_name}其中
region
、zone
、rack
、kubernetes.io/hostname
只是举例,要添加的 Label 名字和数量可以任意定义,只要符合规范且和pd.config
里的location-labels
设置的 Labels 保持一致即可。为 TiDB 节点设置所在的 Node 节点的拓扑信息
从 TiDB Operator v1.4.0 开始,如果部署的 TiDB 集群版本 >= v6.3.0,TiDB Operator 会自动为 TiDB 获取其所在 Node 节点的拓扑信息,并调用 TiDB server 的对应接口将这些信息设置为 TiDB 的 Labels。这样 TiDB 可以根据这些 Labels 将 Follower Read 的请求发送至正确的副本。
目前,TiDB Operator 会自动为 TiDB server 设置
pd.config
的配置中location-labels
对应的 Labels 信息。同时,TiDB 依赖zone
Label 支持 Follower Read 的部分功能。TiDB Operator 会依次获取 Labelzone
、failure-domain.beta.kubernetes.io/zone
和topology.kubernetes.io/zone
的值作为zone
的值。TiDB Operator 仅设置 TiDB server 所在的节点上包含的 Labels 并忽略其他 Labels。
从 TiDB Operator v1.4.0 开始,在为 TiKV 和 TiDB 节点设置 Labels 时,TiDB Operator 支持为部分 Kubernetes 默认提供的 Labels 设置较短的别名。使用较短的 Labels 别名在部分场景下有助于优化 PD 的调度性能。当使用 TiDB Operator 把 PD 的 location-labels
设置为这些别名时,如果对应的节点不包含对应的 Labels,TiDB Operator 自动使用原始 Labels 的值。
目前 TiDB Operator 支持如下短 Label 和原始 Label 的映射:
region
:对应topology.kubernetes.io/region
和failure-domain.beta.kubernetes.io/region
。zone
:对应topology.kubernetes.io/zone
和failure-domain.beta.kubernetes.io/zone
。host
:对应kubernetes.io/hostname
。
例如,如果 Kubernetes 的各个节点上均没有设置 region
、zone
和 host
这些 Labels,将 PD 的 location-labels
设置为 ["topology.kubernetes.io/region", "topology.kubernetes.io/zone", "kubernetes.io/hostname"]
与 ["region", "zone", "host"]
效果完全相同。