客户在广西南宁市青秀区做跨境电商,主站面向东南亚市场,数据库用的是MySQL主从架构。主库在广州机房,从库在南宁机房。最近客户反馈说从库查询的数据不对劲,商品库存和订单状态跟主库对不上,差了大概三四个小时。
排查过程
登录从库,用SHOW SLAVE STATUS\G看了一下复制状态,发现Seconds_Behind_Master这个值显示的是12000多秒,也就是三个多小时。而且这个数字还在慢慢变大,说明复制延迟在持续增加。
再看主库的binlog生成速度,发现每秒写入量比平时高了不少。跟客户确认了一下,当天上午做了一场促销活动,订单量突然增加,主库的写入压力一下子大了很多。
延迟的原因
主从复制是单线程的,从库只有一个SQL线程在回放主库传来的binlog。主库上并发执行的大量写入操作,到了从库这边只能排队一个一个执行,写入量一大,从库就跟不上了。
客户这台从库的配置还比主库低一档,主库是8核16G,从库是4核8G,磁盘也是普通的SSD。配置不对等的情况下,延迟更容易出现。
解决方案
短期方案:先把从库的配置临时升了一档,CPU和内存都翻倍,磁盘IO也做了优化。重启从库之后,复制速度明显提升,Seconds_Behind_Master开始逐渐下降,大概过了两个小时追平了主库。
长期方案:把单线程复制改成多线程复制。MySQL 5.7之后支持基于逻辑时钟的并行复制,可以开启多个SQL线程同时回放binlog。在从库的配置里加了两行:
slave_parallel_workers = 4 slave_parallel_type = LOGICAL_CLOCK
设置完之后重启从库,复制线程变成了4个,并发回放能力提升了三倍多。再模拟了一次促销流量,从库延迟控制在了10秒以内。
还发现一个隐患
检查主库的binlog保留策略,发现binlog只保留了三天。如果从库故障超过三天,就没法从主库同步了,需要重新搭建主从。把binlog保留时间改成了七天,同时定期备份binlog到对象存储,确保有足够的时间窗口来处理故障。
客户那边的情况
客户在南宁青秀区做东南亚跨境电商,主要卖小家电和家居用品。从库主要是用来做报表查询和数据分析的,延迟太大报表就不准了。这次调整之后,客户说后台的销售报表终于跟实时数据对得上了。
一点补充
主从复制延迟是MySQL运维中很常见的问题。如果从库延迟持续增加,先看主库写入量是不是突然变大了,再看从库配置是否跟得上。如果业务允许,开启多线程复制能明显改善延迟。如果延迟实在追不上,可能要考虑分库分表或者换用其他方案。
