写点什么

TiDB 上百 T 数据拆分实践

  • 2022 年 7 月 11 日
  • 本文字数:4416 字

    阅读完需:约 14 分钟

作者: jiaxin 原文来源:https://tidb.net/blog/57fbca58


TiDB 上百 T 数据拆分实践

背景

提高 TiDB 可用性,需要把多点已有上百 T TiDB 集群拆分出 2 套




挑战

  • 1、现有需要拆分的 12 套 TiDB 集群的版本多 (4.0.9、5.1.1、5.1.2 都有),每个版本拆分方法存在不一样

  • 2、其中 5 套 TiDB,数据量均超过 10T、最大的 TiDB 集群目前数据量 62T、单 TiDB 集群备份集大,消耗大量磁盘空间和带宽资源


空间最大 3 套集群


  • 3、tidb 使用方式多样(每种方式拆分方法不同),有直接读写 tidb,也有 mysql->tidb 汇总分析查询,也有 tidb->cdc-> 下游 hive

  • 4、全量备份 TiDB 在业务高峰期是否会产生性能影响

  • 5、大数据量的拆分数据的一致性保证

方案

目前 TiDB 官方提供的同步工具有:


  • DM 全量 + 增量(该方法无法用于 tidb->tidb,适用于 MySQL->TiDB)

  • BR 全量物理备份 +CDC 增量同步(CDC 同步在 tidb、tikv 节点 OOM 后修复成本高 https://github.com/pingcap/tiflow/issues/3061)

  • BR 全量物理备份 +binlog 增量(类似于 MySQL 记录所有变更的 binlog 日志,TiDB binlog 由 Pump(记录变更日志)+Drainer(回放变更日志) 组成,我们采用该方法进行全量 + 增量同步拆分)






备份与恢复工具 BR


TiDB Binlog


因 TiDB 拆分 BR 全量物理备份 +binlog 增量涉及周期长,我们分为 4 个阶段进行

第一阶段

1、清理现有 TiDB 集群无用数据


按月分表 tidb 库有无用的表,如 3 个月前的 xxxx 日志表


2、升级 GZ 现有 15 套 TiDB 集群(12 套 TiDB 集群需要 1 分为 2)版本至 5.1.2


趁这次拆分统一 GZ tidb 版本,解决挑战 1


set @@global.tidb_analyze_version = 1;
#tidb_analyze_version为2时出现OOM几率大,5.4版本开始该默认值从2改为1
https://github.com/pingcap/tidb/issues/31748
复制代码

第二阶段

1、新机器部署好相同版本 5.1.2TiDB 集群


set @@global.tidb_analyze_version = 1;


2、目的端,源端所有 tikv tiflash 挂载好 NFS,pd 节点上安装好 BR


Exteral storge 采用腾讯云 NFS 网盘,保障 tikv 备份目的端和还原全量来源端都能在同一目录,NFS 网盘空间自动动态增加 + 限速备份以应对挑战 2


3、独立 3 台机器部署好 12 套 TiDB 集群 pump 收集 binlog(端口区分不同 TiDB 集群)


pump,drainer 采用独立 16C, 32G 机器保障增量同步最大性能

注意:为保障 tidb 计算节点的可用性,需设置 ignore-errorbinlog 关键参数


server_configs:
tidb:
binlog.enable: true
binlog.ignore-error: true
复制代码


4、修改 pump 组件 GC 时间为 7 天


binlog 保留 7 天保障全量备份 -> 到增量同步过程能接上


pump_servers:
- host: xxxxx
config:
gc: 7
#需reload重启tidb节点使记录binlog生效
复制代码


5、备份 TiDB 集群全量数据至 NFS Backup & Restore 常见问题


注意:每个 TiDB 集群在同一个 NFS 建不同备份目录

注意:源老 TiDB 集群分别限速 (备份前后对读写延迟时间基本无影响) 进行错峰全量备份 (存在之前多个 TiDB 集群同时备份把 NFS 3Gbps 网络带宽打满情况) 以减轻对现有 TiDB 读写、NFS 的压力以应对挑战 2


mkdir -p /tidbbr/0110_dfp
chown -R tidb.tidb /tidbbr/0110_dfp
#限速进行全业务应用库备份
./br backup full \
--pd "xxxx:2379" \
--storage "local:///tidbbr/0110_dfp" \
--ratelimit 80 \
--log-file /data/dbatemp/0110_backupdfp.log
#限速进行指定库备份
./br backup db \
--pd "xxxx:2379" \
--db db_name \
--storage "local:///tidbbr/0110_dfp" \
--ratelimit 80 \
--log-file /data/dbatemp/0110_backupdfp.log

12.30号45T TiDB集群全量备份耗时19h,占用空间12T
[2021/12/30 09:33:23.768 +08:00] [INFO] [collector.go:66] ["Full backup success summary"] [total-ranges=1596156] [ranges-succeed=1596156] [ranges-failed=0] [backup-checksum=3h55m39.743147403s] [backup-fast-checksum=409.352223ms] [backup-total-ranges=3137] [total-take=19h12m22.227906678s] [total-kv-size=65.13TB] [average-speed=941.9MB/s] ["backup data size(after compressed)"=12.46TB] [BackupTS=430115090997182553] [total-kv=337461300978]
复制代码


6、每个新建 TiDB 集群单独同步老 TiDB 集群用户密码信息


注意:BR 全量备份不备份 tidb mysql 系统库,应用、管理员用户密码信息可用开源 pt-toolkit 工具包 pt-show-grants 导出


7、恢复 NFS 全量备份至新 TiDB 集群


注意:新 TiDB 集群磁盘空间需充裕,全量备份还原后新 TiDB 集群占用空间比老 TiDB 集群多几个 T,和官方人员沟通是由于还原时生成 sst 的算法是 lz4,导致压缩率没有老 TiDB 集群高

注意:tidb_enable_clustered_index,sql_mode 新老 TiDB 集群这 2 参数必须一致




8、tiup 扩容 drainer 进行增量同步


扩容前确认下游 checkpoint 信息不存在或已清理

如果下游之前接过 drainer,相关位点在目标端 tidb_binlog.checkpoint 表中,重做的时候需要清理

注意:因源最大 TiDB 集群长期平均写入 TPS 在 6k 左右,在增大 worker-count 回放线程数后,尽管目的端域名解析到 3 个 tidb 节点,单个 drainer 增量还是无法追上延迟(回放速度最高在 3k TPS),后和 TiDB 官方沟通改成按 3 个 drainer(不同 drainer 同步不同库名)并行增量同步延迟追上(3 个 drainer 增量让“漏斗”没有堆积,源流入端数据能及时到达目标流出端)

注意:多个 drainer 并行增量必须指定目的端 checkpoint.schema 为不同库 drainer 配置说明




#从备份文件中获取全量备份开始时的位点TSO
grep "BackupTS=" /data/dbatemp/0110_backupdfp.log
430388153465177629


#第一次一个drainer进行增量同步关键配置
drainer_servers:
- host: xxxxxx
commit_ts: 430388153465177629
deploy_dir: "/data/tidb-deploy/drainer-8249"
config:
syncer.db-type: "tidb"
syncer.to.host: "xxxdmall.db.com"
syncer.worker-count: 550



#第二次多个drainer进行并行增量同步
drainer_servers:
- host: xxxxxx
commit_ts: 430505424238936397 #该位点TSO为从第一次1个drainer增量停止后目的端checkpoint表中的Commit_Ts
config:
syncer.replicate-do-db: [db1,db2,....]
syncer.db-type: "tidb"
syncer.to.host: "xxxdmall.db.com"
syncer.worker-count: 550
syncer.to.checkpoint.schema: "tidb_binlog2"

复制代码


1 个 drainer 进行增量延迟越来越大




3 个 drainer 进行并行增量同步最慢一条增量链路:9h 追了近 1 天数据




3 个 drainer 并行同步目的端写入 1.2w TPS > 源端 6k 写入 TPS




9、配置新建 tidb grafana&dashboard 域名


建 grafana、dashboard 的域名指向生产 nginx 代理,由 nginx 代理 grafana 端口,dashboard 端口

第三阶段

1、check 新老 TiDB 集群数据同步一致性情况


TiDB 在全量和增量时会自行进行数据一致性校验,我们主要关注增量同步延迟情况,并随机 count(*) 源目的端表




#延迟检查方法一:在源端TiDB drainer状态中获取最新已经回复TSO再通过pd获取延迟情况
mysql> show drainer status;
+-------------------+-------------------+--------+--------------------+---------------------+
| NodeID | Address | State | Max_Commit_Ts | Update_Time |
+-------------------+-------------------+--------+--------------------+---------------------+
| xxxxxx:8249 | xxxxxx:8249 | online | 430547587152216733 | 2022-01-21 16:50:58 |




tiup ctl:v5.1.2 pd -u http://xxxxxx:2379 -i
» tso 430547587152216733;
system: 2022-01-17 16:38:23.431 +0800 CST
logic: 669




#延迟检查方法二:在grafana drainer监控中观察
tidb-Binlog->drainer->Pump Handle TSO中current值和当前实际时间做延迟比较
曲线越陡,增量同步速率越快
复制代码


2、tiflash 表建立 &CDC 同步在新 TiDB 集群建立 & 新 mysql->tidb 汇总同步链路闭环 (DRC-TIDB)


tiflash

源端 tidb 生成目的端 新建 tiflash 语句




SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = '<db_name>' and TABLE_NAME = '<table_name>'
SELECT concat('alter table ',table_schema,'.',table_name,' set tiflash replica 1;') FROM information_schema.tiflash_replica where table_schema like 'dfp%';
复制代码


CDC 链路闭环

在老 TiDB CDC 同步中选取 1 个 TSO 位点在新 TiDB 中建立 CDC 至 kafka topic 同步

DRC-TIDB 链路闭环(自研 mysql->tidb 合库合表同步工具)

上图左右为 DRC-TIDB 拆分前后状态

1、左老 drc-tidb 同步规则 copy 到右新 drc-tidb,不启动 drc-tidb 同步 (记录当前时间 T1)

2、drainer 同步现有 TiDB 数据至新建 TiDB 链路启用安全模式 replace(syncer.safe-mode: true) 插入

3、修改左 drc-tidb 同步源目的地址为闭环,并启动 drc-tidb(记录当前时间 T2)

4、右 tidb grafana drainer 监控中 check 当前同步时间 checkpoint 是否 >=T2(类似于tikv follower-read),若没有则等待延迟追上

5、右 tidb 集群增量同步修改 edit-config drainer 配置文件,去掉 mysql-tidb 同步的库名(所有库同步增加指定库名同步)并 reload drainer 节点


 commit_ts: 431809362388058219
config:
syncer.db-type: tidb
syncer.replicate-do-db:
- dmall_db1 该DB为直接读写
- dmall_db2 该DB为从mysql同步而来,需去掉
复制代码


6、修改右 drc-tidb 同步源目的地址为闭环,并启动右 drc-tidb(drc-tidb 采用幂等同步,会重复消费 copy 同步规则 T1 时间到现在 now 的 mysql binlog)


3、每个新 TiDB 集群 ANALYZE TABLE 更新表统计信息


不是必须,更新统计信息为最新可以避免查询 sql 索引选择走错

第四阶段

1、左 tidb 集群应用域名解析至新建 tidb 计算节点



2、批量 kill 右 TiDB 集群左应用的连接


存在脚本多次批量 kill tidb pid; 在右 tidb 节点依然有大量左应用的连接,因此左应用滚动重启后右 tidb 节点左应用连接释放


3、移除老 TiDB 集群 -> 新 TiDB 集群增量同步 drainer 链路


注意:因多个 TiDB 集群共用的 1 台高配 drainer 机器,node_exporter(采集机器监控 agent) 也是多个 TiDB 集群共用,当 A TiDB 集群停止 drainer 链路,B C TiDB 集群会报 node_exporter 不存活告警

总结

  • 不同 TiDB 版本的升级统一版本很有必要,一是拆分方法的通用,减少拆分的复杂度,二是享受新版本的特性,减低运维管理成本

  • 目标 TiDB 集群磁盘空间需足够充裕

  • 在源 TiDB 写入压力大时增量同步 binlog 到目的端的延迟保障需要 drainer 按库名进行并发增量同步

  • TiDB 拆分涉及步骤多,能提前做的步骤就提前错,真正总拆分的时间窗口很短

  • 感谢 TiDB 官方社区对我们的技术支持,路漫漫其修远兮,我们将上下而求索


#


#


发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
TiDB上百T数据拆分实践_迁移_TiDB 社区干货传送门_InfoQ写作社区