敏捷模式支持两节点部署

基本概念

阅读本文时,建议先区分以下概念:

  • SYNC:集群按双节点同步形态运行。
  • ASYNC:集群已经进入单节点接管状态。
  • arbiter:自动降级前的仲裁机制,用于判断发生故障后,哪一个节点可以自动接管服务。
  • 存活节点:当前仍可对外提供服务的节点。
  • 故障节点:当前发生故障、无法继续对外提供服务的节点。

概述

普通的基于 Raft 协议的双副本部署,不能容忍单副本故障,一个节点彻底失联后,另一个节点不能继续安全读写。

even-replicas 解决该场景下的基本思路如下:

  • 正常情况下,集群以两个节点运行,状态为 SYNC
  • 当一个节点持续故障超过阈值,且另一个节点通过仲裁后,集群会切换到 ASYNC 状态。
  • 集群进入 ASYNC 后,仅存活节点对外提供服务,故障节点不再提供服务。
  • 故障节点恢复后,系统会持续检查恢复情况,持续尝试恢复到 SYNC 状态。

两副本敏捷模式部署拓扑

global: kind: fusion user: "tidb" ssh_port: 22 deploy_dir: "/tidb-deploy" data_dir: "/tidb-data" listen_host: 0.0.0.0 arch: "amd64" server_configs: pd: # 启动 placement-rules 并且确保副本数是 2 replication.enable-placement-rules: true replication.max-replicas: 2 # isolation-level 必须引用 location-labels 中的某个 label replication.location-labels: ["dc"] replication.isolation-level: "dc" replication-mode: # 启动双副本模式 replication-mode: "even-replicas" # 故障发生时,降级超时等待时间 even-replicas.downgrade-timeout: 20s # 以下三模式三选一: # 预设主从模式 #even-replicas.arbitration.type: "preset" #even-replicas.arbitration.primary-label: "dc1" # 脚本仲裁模式 #even-replicas.arbitration.type: "custom-script" #even-replicas.arbitration.script: ["/bin/bash", "/root/xxx.sh"] # 仲裁服务模式 #even-replicas.arbitration.type: "service" #even-replicas.arbitration.endpoints: ["http://10.10.10.10:4320"] tikv: # 需要关闭 hibernate regions,否则 RTO 会比较大 raftstore.hibernate-regions: false tidb_servers: - host: tidb-1.local - host: tidb-2.local pd_servers: # even-replicas 当前面向双 PD 部署场景 - host: tidb-1.local config: - # 每个 PD 节点都必须配置 isolation-level 对应的本地标签值 - # 例如 isolation-level = "dc" 时,这里需要写 labels: {dc: "dc1"} labels: {dc: "dc1"} - host: tidb-2.local config: labels: {dc: "dc2"} tikv_servers: - host: tidb-1.local config: server.labels: { dc: "dc1" } - host: tidb-2.local config: server.labels: { dc: "dc2" }

备注:

  • replication.isolation-level 必须是 replication.location-labels 中的一个,并且每个 PD 节点都必须配置对应的本地 labels[isolation-level]
  • replication.enable-placement-rules 必须设置为 true;否则 even-replicas 会被判定为配置非法,无法进入正常流程。
  • 集群中的 placement rule 必须只有 1 条默认规则,并满足:role = votercount = 2start_key_hex = ""end_key_hex = ""is_witness = falseisolation_level = replication.isolation-level

三种降级仲裁方式

even-replicas 支持三种仲裁方式:

类型说明
preset使用固定主节点标签进行仲裁
service调用外部仲裁服务(Tiarbiter/TEM)
custom-script调用本地脚本完成仲裁

preset

[replication-mode.even-replicas.arbitration] type = "preset" primary-label = "dc1"

此例中:

  • dc2 故障,dc1 可以自动降级提供服务。
  • dc1 故障,dc2 不能自动降级提供服务。

service

[replication-mode.even-replicas.arbitration] type = "service" endpoints = ["http://arbiter-1:8080"]

如需部署仲裁服务,可在 TiUP 拓扑文件中增加 tiarbiter_servers 配置。

拓扑最小写法如下:

tiarbiter_servers: - host: 10.0.1.30

在这种写法下,默认值如下:

  • port: 4320
  • deploy_dir: deploy/tiarbiter-4320
  • data_dir: data
  • log_dir: log
  • log_level: info

拓扑完整写法如下:

global: user: "tidb" ssh_port: 22 deploy_dir: "/data1/tidb-deploy" data_dir: "/data1/tidb-data" tiarbiter_servers: - host: 10.0.1.30 port: 4320 deploy_dir: "/data1/tidb-deploy/tiarbiter-4320" data_dir: "/data1/tidb-data/tiarbiter-4320" log_dir: "/data1/tidb-deploy/tiarbiter-4320/log" log_level: "info"

仓库自带的完整模板中也包含注释掉的 tiarbiter_servers 示例,可通过以下命令查看:

tiup cluster template --full

custom-script

[replication-mode.even-replicas.arbitration] type = "custom-script" script = ["/opt/tidb/bin/even-replicas-arbiter.sh"]

脚本执行时会附带以下环境变量:

  • CLUSTER_ID
  • LABEL
  • ACTION

其中:

  • ACTION=CONFIRM:询问是否允许自动接管。
  • ACTION=RESET:通知脚本清理仲裁状态。
  • 退出码 0:表示成功。
  • 0:表示拒绝或执行失败。

状态与观测

查看复制模式状态

可通过以下接口查看状态:

curl "http://<pd>/pd/api/v1/replication_mode/status"

SYNC 状态:

{ "mode": "even-replicas", "even-replicas": { "state": "SYNC" } }

AYNC 状态:

{ "mode": "even-replicas", "even-replicas": { "state": "ASYNC", "available_label": "dc1", "replay_progress": 0.42 } }

其中:

  • available_label 用于表示当前集群在 ASYNC 降级状态下,哪一个节点还在继续提供服务
  • replay_progress 用于表示同步恢复进度。

运维手段 force-degrade

接口说明

系统提供一个本地 unsafe 运维 API,可用于对目标存活节点发起强制降级请求:

  • POST /pd/api/v1/admin/unsafe/even-replicas/force-degrade

该接口必须直接请求目标 PD 节点,由目标节点本地处理。

请求参数

请求体如下:

{ "target_label": "dc1", "timeout": 600 }

说明:

  • target_label:必填;必须等于当前收到请求的 PD 节点本地 label。
  • timeout:可选;单位为秒;默认 600

备注:

  • 应当将请求直接发送到需要降级的 pd 端口。
  • 不要依赖随机负载均衡入口。

接口行为

接口可能阻塞数秒到数分钟,降级流程开始时返回 200 OK

常见返回码

返回码说明
200 OKTiKV downgrade 已经启动;不代表所有 Region 已经恢复完成
400 Bad Request参数非法,例如 target_label 为空或与当前节点本地 label 不匹配
409 Conflict当前已有另一个 force-degrade 在执行,或 unsafe recovery 已在运行
412 Precondition Failed当前不在 even-replicas 模式,或 placement rule 尚未就绪 / 配置非法
500 Internal Server Error其他内部错误

在线配置修改与限制

placement rule 写操作限制

even-replicas 模式下,placement rule 仅支持查询,不支持热更新,以下 placement rule 写接口会直接返回 412 Precondition Failed

  • POST /pd/api/v1/config/rule
  • POST /pd/api/v1/config/rules
  • POST /pd/api/v1/config/rules/batch
  • DELETE /pd/api/v1/config/rule/{group}/{id}
  • POST /pd/api/v1/config/rule_group
  • DELETE /pd/api/v1/config/rule_group/{id}
  • POST /pd/api/v1/config/placement-rule
  • POST /pd/api/v1/config/placement-rule/{group}
  • DELETE /pd/api/v1/config/placement-rule/{group}

其他在线修改限制

even-replicas 模式下,除 placement rule 写操作外,还存在以下在线修改限制:

  • /config/replication:不支持在线修改 enable-placement-rulesmax-replicaslocation-labelsisolation-level
  • /config/replication-mode:不支持在线修改 replication-mode.even-replicas.downgrade-timeoutreplication-mode.even-replicas.arbitration 及其所有子字段。
  • /config/replication-mode:不支持在运行时把复制模式从 majority / dr-auto-sync 切换到 even-replicas,或从 even-replicas 切回其他模式。