Mysql主从复制

88 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.什么是主从复制

主从复制是用来建立一个和主数据库完全一样的数据库,称为从数据库;
主数据库一般是准实时的业务数据库。

2.主从复制的作用

  • 1.做数据的热备 作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。\
  • 2.有利于架构的扩展 业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。\
  • 3.读写分离,使数据库能支撑更大的并发 在报表服务中尤其重要。由于部分报表服务的sql语句非常的慢,导致锁竞争,影响前台服务。如果前台使用master,报表服务使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

3.主从复制的原理

image.png

  • 第一步:Master节点将数据的改变记录成二进制日志(Binary log,简称binlog),当Master上的数据发生改变时,则将其改变写入二进制日志中。
  • 第二步:Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求Master的二进制事件。
  • 第三步:同时Master节点为Slave的每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成sql语句逐一执行,使得其数据和Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。

4.主从同步的延时如何解决?

虽然主从架构帮我们解决读的瓶颈,但是由于主从之间需要数据同步,这天然就存在一定延时。
在这延时窗口期内,从库的读只能读到一个旧数据,这就是主从同步的延时问题
总共有五种解决方案
为了解决主从延迟,数据不一致的情况,我们可以采用以下这几种方案:
忍受大法
数据库同步写方案
选择性强制读主库
中间件选择路由法
缓存路由大法

方案1:忍受大法

不管他,反正过了这个延时窗口数据就会是一致的,如果业务对数据的一致性要求不高,可以采用这种方法。

方案2:数据同步写方案

主从数据同步方案,一般都是采用的异步方式同步给从库。
我们可以将其修改为同步方案,主从同步完成,主库上的写才能返回。

image.png 流程如下:

  1. 业务系统发起写操作,数据写主库
  2. 写请求需要等待主从同步完成才能返回
  3. 数据读从库,主从同步完成就能读到最新数据 这种方案,我们只需要修改数据库之间同步配置即可,业务层无需修改,相对简单。
    不过,由于主库写需要等待主从完成,写请求的时延将会增加,吞吐量将会降低。
    这一点对于现在在线业务,可能无法接受。

方案3:选择性强制读主库

对于需要强一致的场景,我们可以将其的读请求都操作主库,这样读写都在主库,就没有不一致的情况。

image.png 这种方案业务层需要改造一下,将其强制性读主,相对改造难度较低。
不过这种方案相对于浪费了另一个数据库,增加主库的压力。

方案4:中间件路由法

这种方案需要使用一个中间件,所有数据库操作都先发到中间件,由中间件再分发到相应的数据库。

image.png 这时流程如下:

  1. 写请求,中间件将会发到主库,同时记录一下此时写请求的 key(操作表加主键等)
  2. 读请求,如果此时 key 存在,将会路由到主库
  3. 一定时间后(*经验值*),中间件认为主从同步完成,删除这个 key,后续读将会读从库
延迟窗口内的读给打到主库,一定时间后,中间件认为延迟窗口的时间到了,主从同步复制完成了,后续请求可以打到从库,即不同时间打到不同库

方案5:缓存路由法

这种方案与中间件的方案流程比较类似,不过改造成本相对较低,不需要增加任何中间件。

image.png 这时流程如下:

  1. 写请求发往主库,同时缓存记录操作的 key,缓存的失效时间设置为主从的延时
  2. 读请求首先判断缓存是否存在
    • 若存在,代表刚发生过写操作,读请求操作主库
    • 若不存在,代表近期没发生写操作,读请求操作从库
将redis的key的过期时间设置为主从的延时,这样就可以决定请求应该打到主库还是从库

5.主从复制需要的配置

主服务器

  1. 开启二进制日志
  2. 配置唯一的server-id
  3. 获得master二进制日志文件名及位置
  4. 创建一个用于slave和master通信的用户账号 从服务器
  5. 配置唯一的server-id
  6. 使用master分配的用户账号读取master二进制日志
  7. 启用slave服务