TIDB-- 不容易发现的 lightning tidb-backend 模式导入优化
【是否原创】是
【首发渠道】TiDB 社区
【目录】
[项目背景]()
[问题描述]()
[分析原因]()
[解决方案]()
[脚本共享]()
【正文】
项目背景
近日,一个主 AP 业务项目 MyCat 下迁 TIDB 迁移,原分库分表架构(16 台 server) AP 大 SQL 普遍需 2 小时跑出结果,POC 实测(5 台 server)该类 SQL 调优后 TiDB 下 20 分钟内均能出结果,能获得近乎 5 倍下迁收益。
问题描述
原有业务场景中,需每月定期往数据库以 LOAD LOCAL FILE 的方式导入约 1 亿左右宽表数据,但原有方式测下来,TiDB 的 LOAD 耗时约 8 小时,刨除 POC 性能没有生产好等原因,也是运维人员不可接受的。
因为 TiDB AP SQL 上的优化,业务方也有了加速数据更新的想法,即:将 LOAD 数据周期从每月改为每周。如果该这个问题无法解决,该方案基本无法改变。
而且,因项目原因在低于 TiDB 官网硬件标准的 非 SSD 磁盘又测了一版结果,测试过程中暴露出 LOAD LOCAL FILE 当时导入数据无法保证原子性导入的问题。具体表现为由于 TiKV 写入过慢报错 LockNotFound 事务锁被清除,详情参考官网解释,但该场景中,可能出现 LOAD 进去 5 千万数据导入失败,此时需要反向 Delete 掉已导入的数据,代价极高,即使分批 del 也很难判定本次导入了哪些数据,无很好方式业务实现方法。
总结问题点:
TiDB 同 MySQL 用 LOAD 方式导入 csv 文件过慢
LOAD 方式导入数据无法保证原子性导入
分析原因
导入过慢的原因是 LOAD 是单线程方式工作,没有利用并发多线程导入加速。
LOAD 走的是 batch insert 接口,默认会将 csv 文件切分为多份、构成多个小事务提交。
注意:⚠️MySQL 的实现也是 batch insert,所以理论上也存在该风险。
解决方案
利用 Lightning 的断点续传功能保证原子性导入, 具体原理:假设切分成了 50 个 csv 文件,lightning 导入某种原因中途断掉,所有 lightning 线程停止工作,重启后会基于 check_point 读出表信息、排序目录、taskid(关键),可以顺着 taskid 继续下一个 task 完成断点续传,实现最终一致;
导入前 Shell 脚本拆分 csv 文件为多份,配合 lightning 参数 region-concurrency, 该参数默认表示 CPU 实际占用核数,默认 100% 占用。其实一旦拆分文件超过该值已经无意义了,并没有加速上的优化意义。
注意:⚠️但可以依据日志中打印的文件号,推断导入进度,其实认为 mysql client count 也可以实现同样目的。
脚本共享
虽然 tidb-lightning 自身存在切分文件为 256M 的功能,但要求 strict-format = true;
因为该项目数据由 Teradata 上导出,且受限企业 csv 文件规范要求无法更改;
所以我为该项目做了个处理脚本取名 TiChange_for_lightning 希望能帮到大家,具体使用参考 README!
注意:⚠️该工具除格式转换外,仅对 tidb-backend 模式导入速度进行优化,其他模式(importer、local)并无速度上优化。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/0bb3391ba0353e31a9a55b36f】。文章转载请联系作者。
评论