Mysql主从复制原理及保证数据一致性
提升数据库的并发能力
提在实际工作中,我们常常将Redis作为缓存与MySQL来配合使用,当有请求的时候,首先会从缓存中进行查找,如果存在就直接取出,如果不存在再访问数据库。这样就提升了读取的效率,也减少了对后端数据库的访问压力。
此外,对于一般数据库应用而言,都是读多写少的,当数据库读取数据压力较大时,我们可以从成本较小的方案开始优化,可以首先考虑优化SQL和索引,其次就是缓存策略,最后才是主从架构。
主从复制的作用
- 读写分离。 在读多写少的情况下,可以采用读写分离,主库当做写库,然后根据实际需要,选择使用多个读库,分散读的压力,提高并发性。
- 数据备份。 主从复制其实就相当于一种热备份的机制。
- 实现高可用。 数据备份其实就是一种冗余机制,当主服务器出现故障是时,可以切换到从服务器上,提高服务器可用性。
主从复制原理
- 实际上主从同步的原理就是基于binlog进行数据同步的。在主从复制过程中,会基于3个线程来操作,一个主库线程,两个从库线程。
- 二进制日志转储线程是一个主库线程。 当从库线程连接的时候,主库可以将二进制日志发送给从库,当主库读取事件的时候,会在Binlog上加锁,读取完成之后,再将锁释放掉。
- 从库I/O线程会连接到主库,向主库发送请求更新Binlog。 这时从库的I/O线程就可以读取到主库的二进制日志转储线程发送的Binlog更新部分,并且拷贝到本地的中继日志。
- 从库SQL线程会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。
总结起来就是三步:
步骤1:Master将写操作记录到二进制日志(binlog),这些记录叫做二进制日志事件(binary log events);
步骤2:Slave 将 Master 的 binary log events拷贝到它的中继日志(relay log);
步骤3:Slave重做中继日志中的事件,将改变应用到自己的数据库中。
搭建
TODO 此处省略,待补充
如何解决数据一致性问题
进行主从同步的内容是二进制日志,它是一个文件,在进行网络传输的过程中就一定会存在主从延迟,这样就可能造成用户在从库上读取的数据不是最新的数据,也就是主从同步中的数据不一致性问题。
方案一、异步复制
- 异步模式就是客户端提交COMMIT之后不需要等从库返回任何结果,而是直接将结果返回给客户端,这样做的好处是不会影响主库写的效率。
- 但这样可能会存在主库宕机,而Binlog还没有同步到从库的情况,也就是此时的主库和从库数据不一致。
- 这时候从从库中选择一个作为新主,那么新主则可能缺少原来主服务器中已提交的事务。所以,这种复制模式下的数据一致性是最弱的。
方案二、半同步复制
- 半同步复制的原理是在客户端提交COMMIT之后不直接将结果返回给客户端,而是等待至少有一个从库接收到了Binlog,并且写入到中继日志中,再返回给客户端。
- 这样做的好处是提高了数据的一致性,当然相比于异步复制来说,至少多增加了一个网络连接的延迟,降低了主库写的效率。
- 在MySQL5.7版本中还增加了一个参数,可以对应答的从库数量进行设置,默认为1,也就是说只要有1个从库进行了响应,就可以返回给客户端。如果将这个参数调大,可以提升数据一致性的强度,但也会增加主库等待从库响应的时间。
方案三、组复制
- 异步复制和半同步复制都无法最终保证数据的一致性问题,半同步复制是通过判断从库响应的个数来决定是否返回给客户端,虽然数据一致性相比于异步复制有提升,但仍然无法满足对数据一致性要求高的场景。 组复制技术MGR很好地弥补了这两种复制模式的不足,它是MySQL在5.7.17版本中推出的一种新的数据复制技术,是基于Paxos协议的状态机复制。