一般来说,slave的延迟相对于master是比较大的。根本原因是slave上的复制线程不能真正并发。简单的说,在master上,事务的提交是以并发的方式完成的(基于InnoDB引擎),而在slave上,复制线程只有一个sql线程用于binlogapply,难怪slave高并发时远远落后于master。ORACLEMySQL5.6开始支持多线程复制,配置选项slave_parallel_workers可以在slave上实现多线程并发复制。但是它只能支持一个实例下多个数据库之间的并发复制,并不能真正实现多表的并发复制。所以在大并发负载下,slave还是没办法及时赶上master,需要想办法优化。还有一个很重要的原因就是传统的MySQL复制是异步的(asynchronous),也就是说master提交之后,在slave上再次申请,并不是真正的同步。即使是后来的Semi-syncRepication(半同步复制)也不是真正的同步,因为它只是保证事务传输到slave,而不需要等到事务被确认成功提交。既然是异步的,肯定会有一些延迟。所以,严格来说,MySQL复制不能称为MySQL同步(处女座面试官在面试时可能会刷掉所有说是MySQL同步的东西)。另外,在很多人的印象中,slave的重要性相对较低,所以不会提供与master同等配置级别的服务器。有些甚至不仅使用更差的服务器,而且还在其上运行多个实例。综合这两个主要原因,如果slave想尽可能的跟上master的进度,可以尝试以下方法:使用MariaDB分布式,实现了比较真实意义上的并行复制,其效果是远比OracleMySQL好很多。在我的场景中,使用MariaDB作为从实例几乎总是可以及时跟上主实例。如果不想用这个版本,等5.7正式版发布即可;关于MariaDB的ParallelReplication的详细介绍,请参考:ReplicationandBinaryLogServerSystemVariables#slave_parallel_threads-MariaDBKnowledgeBase每张表必须显式指定主键,如果不指定主键会导致全表扫描行模式下的每一次修改,尤其是大表,延迟会比较严重,甚至整个从库都会挂掉。参考案例:mysql主键缺失导致备库挂掉;多在应用程序端做,让MySQL端少做,尤其是与IO相关的活动。甚至消除一些写请求;进行适当的分库分表策略,降低单库单表复制的压力,避免单库单表的压力导致整个实例的复制延迟;其他提升IOPS性能的方法,根据效果的优劣,我做了一个简单的排名:换成SSD或者PCIeSSD等IO设备,其IOPS能力会是几百,几千,甚至上百是普通15KSAS盘的数千倍;对于物理内存,相应增加InnoDBBufferPool的大小,让更多的热数据存放在内存中,降低物理IO的频率;将文件系统调整为XFS或ReiserFS,相比ext3可以大幅提升IOPS能力。在高IOPS压力下,比ext4有更稳定的IOPS性能(有人认为XFS在特殊场景下会出大问题,但我们还没有遇到磁盘剩余空间不足10%时数据丢失的情况);调整RAID级别为raid1+0,相对于raid1和raid5,IOPS性能有提升。如果都是SSD设备,可以两块盘做RAID1,或者多块快盘做RAID5(也可以设置全局热备盘提高阵列的容错能力),甚至有的有钱用户直接组合多个SSD磁盘RAID50;调整RAID的写缓存策略为WB或FORCEWB。详见:常用PC服务器阵列卡、硬盘健康监测及PC服务器阵列卡管理简易手册;调整kernelioscheduler,优先使用deadline,如果是SSD,可以使用noop策略。与默认的cfq相比,individualtreat下IOPS的性能提升至少是数倍。
