首页 > 编程学习 > 【4. 主从复制】

【4. 主从复制】

发布时间:2022/11/6 15:25:37

文章目录

    • 概述
    • 主从复制作用
    • 主从复制原理
    • 数据同步一致性问题

概述

  • 在实际工作中,经常用RedisMySQL搭配使用,当有请求时,首先会从缓存中进行查询,如果存在就直接取出。如果不存在在访问数据库,这样就提升了读取效率,也减少了后端数据库的访问压力
  • 一般对数据库而言都是读多写少,对于数据库的读取数据压力比较大,所以可以采用数据库集群的方案,做主从架构、进行读写分离,同样可以提升数据库并发处理能力。
    在这里插入图片描述

主从复制作用

在这里插入图片描述

  • 读写分离:由于读多写少,master主库充当写库,salve从库充当读库,当主库更新时,会自动将数据复制到从库中,而客户端读取数据时,会从从库中进行读取,面对读多写少,采用读写分离,在实现高并发的同时,还能对从服务器进行负载均衡,让不同的读请求按照相应策略均匀的分发到不同的从服务器上,而且减少锁表的影响,主库写锁时,从库依旧可以读。
  • 数据备份:通过主从复制将主库上的数据复制到了从库上,相当于一种热备份机制,也就是在主库正常运行的情况下的备份,不会影响到服务
  • 高可用性:数据库备份实际上是一种冗余的机制,通过冗余的方式可以换取数据库的高可用性,也就是当服务器出现故障宕机情况下们可以切换到从服务器上,保证服务的正常运行。

主从复制原理

Slave 会从 Master 读取 binlog 来进行数据同步。但是也可能出现主库将数据同步到从库需要500ms,而此时主库刚写完,就要从读库读(假设读200ms),此时就会出现延迟问题,这就需要后面的方法。

实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于 3 个线程 来操作,一个主库线程,两个从库线程
在这里插入图片描述

  • 二进制日志转储线程 :(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件(Event)的时候,会在 Binlog 上 加锁 ,读取完成之后,再将锁释放掉。
  • 从库 I/O 线程 :会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的
    二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志 (Relay log)。
  • 从库 SQL 线程 :会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。
    在这里插入图片描述

复制三步骤

  • 步骤1: Master 将写操作记录到二进制日志( binlog )。
  • 步骤2: Slave Master 的binary log events拷贝到它的中继日志( relay log);
  • 步骤3: Slave 重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的,而且重启后从 接入点 开始复制。

复制的问题

  • 复制的最大问题: 延时

数据同步一致性问题

主从延迟

  • 进行主从同步的内容是二进制日志,它是一个文件,在进行 网络传输 的过程中就一定会 存在主从延迟。这样就可能造成用户在从库上读取的数据不是最新的数据,也就是主从同步中的 数据不一致性 问题。

主从延迟问题原因

  • 在网络正常的时候,日志从主库传给从库所需的时间是很短的,即T2-T1的值是非常小的。即,网络正常情况下,主备延迟的主要来源是备库接收完binlog和执行完这个事务之间的时间差
  • 主备延迟最直接的表现是,从库消费中继日志(relay log)的速度,比主库生产binlog的速度要慢

如何减少主从延迟

  1. 优化SQL,避免慢SQL, 减少批量操作
  2. 提高从库机器的配置 ,减少主库写binlog和从库读binlog的效率差
  3. 尽量采用 短的链路,提升端口带宽
  4. 实时性要求的业务读强制走主库,从库只做灾备,备份。

如何解决一致性问题

  • 如果操作的数据存储在同一个数据库中,那么对数据进行更新的时候,可以对记录加写锁,这样在读取的时候就不会发生数据不一致的情况。但这时从库的作用就是 备份 ,并没有起到 读写分离 ,分担主库读压力 的作用。
  • 读写分离情况下,解决主从同步中数据不一致的问题, 就是解决主从之间 数据复制方式 的问题

在这里插入图片描述

方法 1:异步复制

  • 异步模式就是客户端提交COMMIT之后不需要等从库返回任何结果,而是直接将结果返回给客户端,这样做的好处是不会影响主库写的效率,但可能会存在主库宕机,而Binlog还没有同步到从库的情况,也就是此时的主库和从库数据不一致。这时候从从库中选择一个作为新主,那么新主则可能缺少原来主服务器中已提交的事务。所以,这种复制模式下的数据一致性是最弱的。
    在这里插入图片描述

方法 2:半同步复制

  • 原理是在客户端提交COMMIT之后不直接将结果返回给客户端,而是等待至少有一个从库接收到了Binlog,并且写入到中继日志中,再返回给客户端。这样做的好处就是提高了数据的一致性,当然相比于异步复制来说,至少多增加了一个网络连接的延迟,降低了主库写的效率。
  • 在MvSOL5.7版本中还增加了一个rpl_semi_svnc_master_wait_for_slavecount参数,可以对应答的从库数量进行设置,默认为1,也就是说只要有1个从库进行了响应,就可以返回给客户端。如果将这个参数调大可以提升数据一致性的强度,但也会增加主库等待从库响应的时间。
    在这里插入图片描述

方法 3:组复制

  • 异步复制和半同步复制都无法最终保证数据的一致性问题,半同步复制是通过判断从库响应的个数来决定是否返回给客户端,虽然数据一致性相比于异步复制有提升,但仍然无法满足对数据一致性要求高的场景
  • 首先我们将多个节点共同组成一个复制组,在 执行读写(RW)事务 的时候,需要通过一致性协议层(Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里“大多数人”(对应 Node 节点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1),这样才可以进行提交,而不是原发起方一个说了算。而针对 只读(RO)事务 则不需要经过组内同意,直接 COMMIT 即可。
  • 在一个复制组内有多个节点组成,它们各自维护了自己的数据副本,并且在一致性协议层实现了原子消息和全局有序消息,从而保证组内数据的一致性。

在这里插入图片描述

Copyright © 2010-2022 dgrt.cn 版权所有 |关于我们| 联系方式