大数据导入Mysql踩坑

大数据导入Mysql踩坑

涉及技术简述

微服务架构,k8s部署管理,大数据导入数据库的功能涉及两个服务,一个负责csv文件的定时读取,一个负责文本的处理及入库。
读取服务会将文件内容按OLT粒度涉及的硬件消息,分为约5000条5~10kb的消息发送到kafka指定Topic的同一个分片,此项目分区pattern只设置了2个。均匀分发消息。

处理入库服务则是从消息队列读取消息。然后线程池并发处理。

踩坑及处理

我们的目的是,尽量快速处理约1.5GB的csv文件,具体到数据库的record约1000w左右,最开始预期是15分钟内处理完毕,以下是踩坑:

  1. 入库速度非常缓慢,约2个小时;
    原因:消息队列消息提交偏移量的方法是手动提交,每条消息1执行,提交偏移量阻塞导致。
    解决方案:最先考虑的是采用并发消费,但因为数据要求有顺序性,改为并发消费之后,整个功能就坏掉了。最后采用的是按整个OLT的消息,约5000条,进行一次偏移量提交
    效果:入库由120分钟优化到60分钟。
  2. 数据库死锁频繁;
    原因:间隙锁及where条件未能走索引导致行锁升级为表所
    解决方案:排查了所有的SQL,where条件是有索引的,新增了where条件减小了行锁粒度,并更改了默认的数据库级别,由rr->rc。数据库死锁频率减小,但是仍然存在。
    效果:60分钟到30分钟
  3. 线程池数据不安全;
    原因:数据不安全
    这个是剩余死锁问题的排查,查看数据库的最近死锁记录,发现两个不同表也会死锁,非常奇怪。
    最开始发现消息队列消息似乎是重复消费了,但最后确认是因为线程池里的数据不安全导致的类似现象。
    线程池提交的任务里,有调用一个函数,函数内部会指定一块内存地址保存处理后的数据,处理完毕后返回该地址给调用线程,但是问题就出现在这里,我的排查结果是,该函数返回的地址在多线程情况下,会导致线程不安全的问题。虽然改完之后死锁完全消失,但是最后也没能确认具体原理,待补充。
    效果:速率没有更有效提升

后记

这个功能的优化持续了约10个工作日之久,期间涉及到的技术都是我之前没涉及的。在此列出
kafka:SpringBoot集成的kafkaTemplate、@Listener,分区pattern,并发消费,偏移量提交,kafka管理工具
线程池: 函数涉及的数据安全问题
数据库: 间隙锁,除select以外的命令未走索引导致的行锁与表锁,如何查看数据库死锁日志
k8s: kubectl的常用命令,docker命令,k8s基础概念

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值