记⼀次mysql⼤量插⼊数据,造成插⼊延迟,磁盘IO⾼的性能调优
项⽬场景:
Kafka的数据⼊库到mysql中,由于业务场景的特殊性,Kafka并不是⽤于削峰填⾕的,⽽是要求数据库尽可能的实时存⼊Kafka的最新数据。
问题描述:
虽然Kafka数据量巨⼤,但是过滤完数据后,消费者拉取的每批kafka数据只存⼊五六百条数据,但是随着时间的推移,存⼊数据与kafka的实时数据差距会越来越⼤。⽽且服务器磁盘IO也是将近100%。这可是服务器啊,就算插⼊五六百条数据也是毫秒级别的吧,为什么延迟会越来愈⼤呢?磁盘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;
这种⽅式需要根据具体业务场景评估是否使⽤。因为频繁的开启或关闭索引会对查询造成影响。
mysql下载哪个盘4.利⽤列具有默认值的事实。仅当要插⼊的值与默认值不同时才显式插⼊值。这减少了 MySQL 必须做的解析并提⾼了插⼊速度。
5. 更多insert性能调优,可以查看MYSQL官⽹:
实际上,我只听过修改了values后⾯加多个值的⽅式,解决了延迟的问题。
⼆、mysql如何解决磁盘⾼IO问题
解决磁盘IO问题,主要调整以下⼏个参数:
buffer pool size
innodb_io_capacity 参数
innodb_change_buffering参数RAM
可参考mysql官⽹:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。