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(回放变更日志)组成,我们采用该方法进行全量+增量同步拆分)


因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官方社区对我们的技术支持,路漫漫其修远兮,我们将上下而求索
TiDB上百T数据拆分实践的更多相关文章
- element ui 渲染超过上百条数据时页面卡顿,更流畅的加载大量数据
问题:element ui table渲染上百条数据,页面渲染开始出现延时 解决方案:使用pl-table 注意:设置use-virtual并给定table高度
- 构建数据湖上低延迟数据 Pipeline 的实践
T 摘要 · 云原生与数据湖是当今大数据领域最热的 2 个话题,本文着重从为什么传统数仓 无法满足业务需求? 为何需要建设数据湖?数据湖整体技术架构.Apache Hudi 存储模式与视图.如何解决冷 ...
- 从SQL Server到MySQL,近百亿数据量迁移实战
从SQL Server到MySQL,近百亿数据量迁移实战 狄敬超(3D) 2018-05-29 10:52:48 212 沪江成立于 2001 年,作为较早期的教育学习网站,当时技术选型范围并不大:J ...
- Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9941208.html 主讲人:大石头 时间:2018-11-10 晚上20:00 地点:钉钉群(组织代码 ...
- [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
[翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...
- 阿里HBase的数据管道设施实践与演进
摘要:第九届中国数据库技术大会,阿里巴巴技术专家孟庆义对阿里HBase的数据管道设施实践与演进进行了讲解.主要从数据导入场景. HBase Bulkload功能.HImporter系统.数据导出场景. ...
- 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架
一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...
- kafka数据迁移实践
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:mikealzhou 本文重点介绍kafka的两类常见数据迁移方式:1.broker内部不同数据盘之间的分区数据迁移:2.不同broker ...
- 测试思想-测试设计 史上最详细测试用例设计实践总结 Part2
史上最详细测试用例设计实践总结 by:授客 QQ:1033553122 -------------------------接 Part1-------------------------- 方法:这里 ...
- Hadoop如何将TB级大文件的上传性能优化上百倍?
这篇文章,我们来看看,Hadoop的HDFS分布式文件系统的文件上传的性能优化. 首先,我们还是通过一张图来回顾一下文件上传的大概的原理. 由上图所示,文件上传的原理,其实说出来也简单. 比如有个TB ...
随机推荐
- 代码块及final关键字的使用
1.代码块的作用:用来初始化类.对象 2.代码块如果有修饰的话,只能使用static. 3.分类:静态代码块 vs 非静态代码块 4.静态代码块 内部可以有输出语句 随着类的加载而执行,而且只执行一次 ...
- 7.MongoDB系列之聚合框架
1. 管道阶段和可调参数 聚合框架基于管道的概念.他由多个阶段组成,每个阶段都会提供一组按钮或可调参数.每个阶段对其输入执行不同的数据处理任务,并生成文档已作为输出传递到下一阶段. 2. 阶段常见操作 ...
- 2022年最新最详细IDEA关联数据库方式、在IDEA中进行数据库的可视化操作(包含图解过程)
文章目录 1.使用IDEA关联Mysql数据库的详细操作步骤 1.1 打开侧边栏的Database 2.2. 选择要连接的数据库(Mysql) 2.3 .输入要连接的数据库.用户名.密码 2.4 .点 ...
- 齐博X1-新建一个空模板并在后台选择
本节实际操作建立一个空模板,并且让后台识别,选择该风格 先在index_style中建立一个目录,命名mystyle并上传我们在mystyle目录中建立一个info.php文件,代码如下:上传后,后台 ...
- golang中的几种并发模式
0.1.索引 https://blog.waterflow.link/articles/1663551951058 1.for- select模式 这种模式通常用在从多个通道读取数据 package ...
- 教你用canvas打造一个炫酷的碎片切图效果
前言 今天分享一个炫酷的碎片式切图效果,这个其实在自己的之前的博客上有实现过,本人觉得这个效果还是挺炫酷的,这次还是用我们的canvas来实现,代码量不多,但有些地方还是需要花点时间去理解的,需要点数 ...
- 京东云开发者| Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现
1 引言 之前介绍了Redis的数据存储及String类型的实现,接下来再来看下List.Hash.Set及Sorted Set的数据结构的实现. 2 List List类型通常被用作异步消息队列.文 ...
- Vue ref 和 v-for 结合(ref 源码解析)
前言 Vue 中组件的使用很方便,而且直接取组件实例的属性方法等也很方便,其中通过 ref 是最普遍的. 平时使用中主要是对一个组件进行单独设置 ref ,但是有些场景下可能是通过给定数据渲染的,这时 ...
- VirtualBox 下 CentOS7 静态 IP 的配置 → 多次踩坑总结,蚌埠住了!
开心一刻 一个消化不良的病人向医生抱怨:我近来很不正常,吃什么拉什么,吃黄瓜拉黄瓜,吃西瓜拉西瓜,怎样才能恢复正常呢? 医生沉默片刻:那你只能吃屎了 环境准备 VirtualBox 6.1 网络连接方 ...
- 成熟企业级开源监控解决方案Zabbix6.2关键功能实战-上
@ 目录 概述 定义 监控作用 使用理解 监控对象和指标 架构组成 常用监控软件分析 版本选型 俗语 安装 部署方式 部署 zabbix-agent 概述 定义 Zabbix 官网地址 https:/ ...





