TiDB 分布式数据库两地三中心建设架构基于 Raft 算法,保证了集群数据一致性和高可用。两地是同城、异地,同城双中心指在同城或临近城市建立独立数据中心,双中心通过高速链路实时同步数据,网络延迟相对较小,另外一个数据中心在异地城市。在这种场景下,可以把业务流量同时派发到同城两个数据中心,通过控制 Region leader 和 PD leader 分布在同城两个数据中心。
以北京和西安为例阐述 TiDB 分布式数据库两地三中心架构部署模型,例中北京有两个机房 IDC1 和 IDC2,异地西安一个机房 IDC3。北京同城两机房之间网络延迟低于 3ms,北京与西安之间网络使用 ISP 专线,延迟约 20ms。
如下图 1 所示为集群部署架构图,具体如下:
图 1 两地三中心集群架构图
该架构具备高可用和容灾备份能力,同时通过 PD 调度限制了 region leader 尽量只出现在同城的两个数据中心,这相比于三数据中心 region leader 分布不受限制的方案优势如下:
因为是基于 Raft 算法,同城两个数据中心同时失效时,只有一个节点存在,不满足 Raft 算法大多数节点存在要求,最终将导致集群不可用及部分数据丢失,这种情况出现的概率是比较小的;另外由于使用到了网络专线,导致该架构成本较高。
下面具体介绍两地三中心架构部署详情。
图2 两地三中心配置详图
北京、西安两地三中心配置详解:
inventory.ini 配置模板信息
## TiDB Cluster Part
[tidb_servers]
TiDB-10 ansible_host=10.63.10.10 deploy_dir=/data/tidb_cluster/tidb
TiDB-11 ansible_host=10.63.10.11 deploy_dir=/data/tidb_cluster/tidb
TiDB-12 ansible_host=10.63.10.12 deploy_dir=/data/tidb_cluster/tidb
TiDB-13 ansible_host=10.63.10.13 deploy_dir=/data/tidb_cluster/tidb
TiDB-14 ansible_host=10.63.10.14 deploy_dir=/data/tidb_cluster/tidb
[tikv_servers]
TiKV-30 ansible_host=10.63.10.30 deploy_dir=/data/tidb_cluster/tikv tikv_port=20171 labels="dc=1,rack=1,zone=1,host=30"
TiKV-31 ansible_host=10.63.10.31 deploy_dir=/data/tidb_cluster/tikv tikv_port=20171 labels="dc=1,rack=2,zone=2,host=31"
TiKV-32 ansible_host=10.63.10.32 deploy_dir=/data/tidb_cluster/tikv tikv_port=20171 labels="dc=2,rack=3,zone=3,host=32"
TiKV-33 ansible_host=10.63.10.33 deploy_dir=/data/tidb_cluster/tikv tikv_port=20171 labels="dc=2,rack=4,zone=4,host=33"
TiKV-34 ansible_host=10.63.10.34 deploy_dir=/data/tidb_cluster/tikv tikv_port=20171 labels="dc=3,rack=5,zone=5,host=34"
[pd_servers]
PD-10 ansible_host=10.63.10.10 deploy_dir=/data/tidb_cluster/pd
PD-11 ansible_host=10.63.10.11 deploy_dir=/data/tidb_cluster/pd
PD-12 ansible_host=10.63.10.12 deploy_dir=/data/tidb_cluster/pd
PD-13 ansible_host=10.63.10.13 deploy_dir=/data/tidb_cluster/pd
PD-14 ansible_host=10.63.10.14 deploy_dir=/data/tidb_cluster/pd
[spark_master]
[spark_slaves]
[lightning_server]
[importer_server]
## Monitoring Part
# prometheus and pushgateway servers
[monitoring_servers]
proth-60 ansible_host=10.63.10.60 prometheus_port=8380 deploy_dir=/data/tidb_cluster/prometheus
[grafana_servers]
graf-60 ansible_host=10.63.10.60 grafana_port=8690 grafana_collector_port=8691 deploy_dir=/data/tidb_cluster/grafana
# node_exporter and blackbox_exporter servers
[monitored_servers]
10.63.10.10
10.63.10.11
10.63.10.12
10.63.10.13
10.63.10.14
10.63.10.30
10.63.10.31
10.63.10.32
10.63.10.33
10.63.10.34
[alertmanager_servers]
alertm ansible_host=10.63.10.60 deploy_dir=/data/tidb_cluster/alertmanager
[kafka_exporter_servers]
## Binlog Part
[pump_servers]
pump-10 ansible_host=10.63.10.10 deploy_dir=/data/tidb_cluster/pump
pump-11 ansible_host=10.63.10.11 deploy_dir=/data/tidb_cluster/pump
pump-12 ansible_host=10.63.10.12 deploy_dir=/data/tidb_cluster/pump
pump-13 ansible_host=10.63.10.13 deploy_dir=/data/tidb_cluster/pump
[drainer_servers]
## Group variables
[pd_servers:vars]
location_labels = ["dc","rack","zone","host"]
## Global variables
[all:vars]
deploy_dir = /data/tidb_cluster/tidb
## Connection
# ssh via normal user
ansible_user = tidb
cluster_name = test
tidb_version = v3.0.5
# process supervision, [systemd, supervise]
process_supervision = systemd
timezone = Asia/Shanghai
enable_firewalld = False
# check NTP service
enable_ntpd = False
set_hostname = False
## binlog trigger
enable_binlog = True
# kafka cluster address for monitoring, example:
# zookeeper address of kafka cluster for monitoring, example:
# zookeeper_addrs = "192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181"
# enable TLS aut hentication in the TiDB cluster
enable_tls = False
# KV mode
deploy_without_tidb = False
# wait for region replication complete before start tidb-server.
wait_replication = True
# Optional: Set if you already have a alertmanager server.
# Format: alertmanager_host:alertmanager_port
alertmanager_target = ""
grafana_admin_user = ""
grafana_admin_password = ""
### Collect diagnosis
collect_log_recent_hours = 2
enable_bandwidth_limit = True
# default: 10Mb/s, unit: Kbit/s
collect_bandwidth_limit = 10000
inventory.ini 作为部署 TiDB 集群的重要配置文件,在配置中建议对所有的组件进行别名设置,以方便使用 ansible-playbook 的 -l 参数操作单一组件的单一实例。
1.TiDB Servers
[tidb_servers]
TiDB-10 ansible_host=10.63.10.10 deploy_dir=/data/tidb_cluster/tidb
TiDB-11 ansible_host=10.63.10.11 deploy_dir=/data/tidb_cluster/tidb
2.TiKV Servers 设置基于 tikv 真实物理部署位置的 label 信息,方便 PD 进行全局管理和调度。
[tikv_servers]
TiKV-30 ansible_host=10.63.10.30 deploy_dir=/data/tidb_cluster/tikv1 tikv_port=20171 labels="dc=1,rack=1,zone=1,host=30"
TiKV-31 ansible_host=10.63.10.31 deploy_dir=/data/tidb_cluster/tikv1 tikv_port=20171 labels="dc=1,rack=2,zone=2,host=31"
3.PD 设置 为 PD 设置 TiKV 部署位置等级信息。
[pd_servers:vars]
location_labels = ["dc","rack","zone","host"]
在两地三中心部署方式下,对于 Labels 的设计也需要充分考虑到系统的可用性和容灾能力,建议根据部署的物理结构来定义 DC、AZ、RACK、HOST 四个等级。
图3 label逻辑定义图
在两地三中心的架构部署中,从性能优化的角度,建议对集群中相关组件参数进行调整。
文件路径:
+ block-cache-size
在 TiKV 单机多实例环境下,需要按照以下公式调整该值。 capacity = MEM_TOTAL * 0.5 / TiKV 实例数量 示例如下:
```
Storage:
block-cache:
capacity: “1G”
```
server:
grpc-compression-type: gzip
调整 PD balance 缓冲区大小,提高 PD 容忍度,因为 PD 会根据节点情况计算出各个对象的 score 作为调度的一句,当两个 store 的 leader 或 Region 的得分差距小于指定倍数的 Region size 时,PD 会认为此时 balance 达到均衡状态。
schedule:
tolerant-size-ratio: 20.0
修改此参数,拉长了异地副本参与选举的时间,尽量避免异地 TiKV 中的副本参与 raft 选举。建议在集群部署完毕后,为 DC3 的 TiKV 增加额外配置后重启 DC3 的TiKV。
raftstore:
raft-min-election-timeout-ticks= 1000
raft-max-election-timeout-ticks= 1020
调度设置 在集群启动后,通过 PD control 工具进行调度策略修改。
config set max-replicas 5
config set label-property reject-leader dc dc3
member leader_priority PD-10 5
member leader_priority PD-11 5
member leader_priority PD-12 5
member leader_priority PD-13 5
member leader_priority PD-14 1