记一次mysql大量插入数据,造成插入延迟,磁盘IO高的性能调优

项目场景:

Kafka的数据入库到mysql中,由于业务场景的特殊性,Kafka并不是用于削峰填谷的,而是要求数据库尽可能的实时存入Kafka的最新数据。

问题描述:

虽然Kafka数据量巨大,但是过滤完数据后,消费者拉取的每批kafka数据只存入五六百条数据,但是随着时间的推移,存入数据与kafka的实时数据差距会越来越大。而且服务器磁盘IO也是将近100%。这可是服务器啊,就算插入五六百条数据也是毫秒级别的吧,为什么延迟会越来愈大呢?磁盘IO为何这么高呢?不应该吧

原因分析:

上面的问题,转化成两个问题来分析:
1.mysql如何进行大批量insert调优
2.mysql如何解决磁盘高IO问题。
按照上面两个问题,进行解决方案的设计。

解决方案:

一、mysql如何进行大批量insert调优
1. insert语句values后加多条数据,进行数据库批量插入。
起初的程序,确实是单条数据insert插入数据库的。当时认为一批数据五六百条,就算单条插入,数据库应该也是毫秒级别的插入吧,应该不会影响插入性能。后来验证后发现这个想法大错特错了。
手动复制了500条数据直接用navicat进行插入操作。结果发现,这500条insert语句,各自单条插入的时间确实很短,都是毫秒甚至纳秒级别的。但是,当500条insert语句顺序执行时,他们的执行是有先后顺序的,也就是说执行完一条后,才会执行另一条,不是并行执行的。所以,这就造成后面的sql需要等待前面的sql执行完后,才开始执行,这500条insert执行完总共用了十几秒的时间。在程序中也是一个道路,当一个连接循环insert语句时,后面的语句一定是等前面的语句执行完后才开始执行的。所以,处理完一批数据的五六百条数据后,已经花费了10几秒甚至更长的时间,这就造成了kafka下一次拉取数据其实等待了很长时间,所以造成了insert数据不能实时跟上kafka数据的问题。

2.关于bulk_insert_buffer_size参数的设置
网上很多博客说加大这个参数的值,允许insert语句拼接更多的values值。通过查看mysql官网描述可以知道,该参数是对MyISAM 引擎下的表才起作用的。而对于InnoDB引擎的表没有作用。所以设置该参数没有作用。

3.索引对插入数据的影响
随着表记录越来越多,索引对插入的性能影响也越来越大,所以,在批量插入数据时,可以把索引关闭,插入完成后,再将索引打开,如下:

ALTER TABLE my_table DISABLE KEYS;

-- Your insert statement

ALTER TABLE my_table ENABLE KEYS;

这种方式需要根据具体业务场景评估是否使用。因为频繁的开启或关闭索引会对查询造成影响。

4.利用列具有默认值的事实。仅当要插入的值与默认值不同时才显式插入值。这减少了 MySQL 必须做的解析并提高了插入速度。

  1. 更多insert性能调优,可以查看MYSQL官网:InnoDB 表的批量数据加载

实际上,我只听过修改了values后面加多个值的方式,解决了延迟的问题。

二、mysql如何解决磁盘高IO问题

解决磁盘IO问题,主要调整以下几个参数:
buffer pool size

innodb_io_capacity 参数

innodb_change_buffering参数

RAM

可参考mysql官网:优化 InnoDB 磁盘 I/O

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的小小酥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值