1. 背景
MySQL的主从同步是一个很成熟的架构,优点为:
①在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;
②在从主服务器进行备份,避免备份期间影响主服务器服务;
③当主服务器出现问题时,可以切换到从服务器。
2. 主从同步延迟产生
mysql的主从复制都是单线程的操作,主库对所有DDL和 DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率也比较高,但slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随机的,不是顺序的,成本高很多,还可能slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡住了,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。master可以并发,Slave_SQL_Running线程却不可以。
当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,还有就是可能与slave的大型query语句产生了锁等待。
3. 解决方案
最简单的减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,比如 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也 可以设置为0来提高sql的执行效率。另外就是使用比主库更好的硬件设备作为slave。
4. 影响因素
如果延迟比较大,一般先确认以下几个因素:
1. 网络延迟
2. master负载
3. slave负载
一般的做法是,使用多台slave来分摊读请求,再从这些slave中取一台专用的服务器,只作为备份用,不进行其他任何操作,就能相对最大限度地达到'实时'的要求了
slave_net_timeout单位为秒 默认设置为 3600秒
含义:当slave从主数据库读取log数据失败后,等待多久重新建立连接并获取数据。
master-connect-retry单位为秒 默认设置为 60秒
含义:当重新建立主从连接时,如果连接建立失败,间隔多久后重试。
通常配置以上2个参数可以减少网络问题导致的主从数据同步延迟