前言

随着业务的增长,一台数据服务器已经满足不了需求了,负载过重。这个时候就需要减压了,实现负载均衡读写分离,一主一丛或一主多从。

主服务器只负责写,而从服务器只负责写,从而提高了效率减轻压力。

主从复制有可以分为:

  • 主从同步:当用户写数据主服务器必须和从服务器同步了才告诉用户写入成功,等待时间比较长。
  • 主从异步:只要用户访问写数据主服务器,立即返回给用户。
  • 主从半同步:当用户访问写数据主服务器写入并同步其中一个从服务器就返回给用户成功

主从复制的形式

  1. 一主一从

    Jk7ZVI.png

  2. 一主多从

Jk7mIP.png

  1. 多主一从

Jk71MQ.png

  1. 双主复制

Jk7UiV.png

  1. 级联复制

img

主从复制的基本原理

MySQL复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收已经记录到日志的数据。当一个从服务器连接到主服务器时,它通知主服务器从服务器日志重读取最后一个更新成功的位置。从服务器接收从那时发生起的任何更新,并在主机上执行相同的更新。然后封锁等待主服务器通知的更新。从服务器执行备份不会干扰主服务器,在备份过程重主服务器可以继续处理更新。

主从复制的好处

  1. 主服务器出现问题,可以切换到从服务器
  2. 可以进行数据库层面的读写分离
  3. 可以在从数据库上进行日常备份

复制过程

Jk7xyQ.png

其中binary log是主服务器的二进制日志

relay log:从服务器的中继日志

**第一步:**master在每个事务更新数据完成之前,将该记录串行的写入到binlog文件中。

**第二步:**salve开启一个IO线程,该线程在master上打开一个普通连接,主要工作是处理binlog。如果读取进入已经跟上master,就进入睡眠状态等待master产生新的事件。IO线程的最终目的是将这些事件写入到中继日志中。

**第三步:**SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主服务器中的数据保持一致。

建立请求的主从的详细流程

  1. 当从服务器连接主服务器是,主服务器会创建一个log dump线程,用于发送binlog的内容。在读取binlog的内容的操作中,会对象主节点上的binlog加锁,当读取完成并发送给从服务器后解锁。
  2. 当从节点上执行start slave命令之后,从节点会创建一个IO线程用来连接主节点,请求主库中更新binlog。IO线程接收主节点binlog dump进程发来的更新之后,保持到relay-log中。
  3. 从节点SQL线程负责读取realy-log中的内容,解析成具体的操作执行,最终保证主从数据的一致性。

两种不同的复制方式

MySQL支持两种不同的日志格式,这两种日志格式也体现了各自的复制方式。

基于语句的复制

基于语句的复制相当于逻辑复制,即二进制日志中记录了操作的语句,通过这些语句在从数据库中重放来实现复制。这种方式简单,二进制文件小,传输带宽占用小。但是基于语句更新依赖于其它因素,比如插入数据时利用了时间戳。因此在开发当中,我们应该尽量将业务逻辑逻辑放在代码层,而不应该放在MySQL中,不易拓展。

基于行数据

基于行的复制相当于物理复制,即二进制日志中记录的时实际更新数据的每一行,这样导致复制的压力比较大,日志占用的空间大,传输带宽占用大。但是这种方式比基于语句的复制根据精确。

延迟问题

当主库的TPS并发较高的时候,由于主库上面时多线程写入的,而从库的SQL线程是单线程的,导致从库SQL可能会跟不上主库的处理速度。

解决方案

  • 网络方面:尽量 保证主库和从库直接的网络稳定,延迟较小。
  • 硬件方面:从库配置更好的硬件,提升随机写的性能。
  • 配置方面:尽量使MySQL的操作在内存中完成,减少磁盘操作。或升级MySQL5.7版本使用并行复制。
  • 建构方面:在事务中尽量对主库读写,其它非事务的读在从库。消除一部分延迟带来的数据库不一致。增加缓存降低一些从库的负载。