Mysql主从复制

Mysql主从复制

1.什么是主从复制

主从复制是用来建立一个和主数据库完全一样的数据库,称为从数据库;

主数据库一般是准实时的业务数据库。

2.主从复制的作用

  • 1.做数据的热备

    作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。

  • 2.有利于架构的扩展

    业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能

  • 3.读写分离,使数据库能支撑更大的并发

    在报表服务中尤其重要。由于部分报表服务的sql语句非常的慢,导致锁竞争,影响前台服务。如果前台使用master,报表服务使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

3.主从复制的原理

  • 第一步: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线程将进入睡眠状态,等待下一次被唤醒。

中继日志通常位于OS缓存中,所以中继日志的开销很小。

简言之可分为下面几个步骤:

一、主库的更新事件会被写到bin log日志中。

二、从库启用slave服务,发起连接,连接到主库。

三、从库创建一个I/O线程,从主库读取bin log日志的内容并写入到relay log日志中。

四、从库创建一个SQL线程,从relay log里面读取内容,将更新内容写入到从库。

复制过程有一个很重要的限制,即复制在Slave上是串行化的,也就是说Master上的并行更新操作不能在Slave上并行操作,所以复制操作是存在延时的

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

虽然主从架构帮我们解决读的瓶颈,但是由于主从之间需要数据同步,这天然就存在一定延时。

在这延时窗口期内,从库的读只能读到一个旧数据,这就是主从同步的延时问题

总共有五种解决方案

为了解决主从延迟,数据不一致的情况,我们可以采用以下这几种方案:

  1. 忍受大法

  2. 数据库同步写方案

  3. 选择性强制读主库

  4. 中间件选择路由法

  5. 缓存路由大法

方案1:忍受大法

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

方案2:数据同步写方案

主从数据同步方案,一般都是采用的异步方式同步给从库。

我们可以将其修改为同步方案,主从同步完成,主库上的写才能返回。

流程如下:

  1. 业务系统发起写操作,数据写主库
  2. 写请求需要等待主从同步完成才能返回
  3. 数据读从库,主从同步完成就能读到最新数据

这种方案,我们只需要修改数据库之间同步配置即可,业务层无需修改,相对简单。

不过,由于主库写需要等待主从完成,写请求的时延将会增加,吞吐量将会降低。

这一点对于现在在线业务,可能无法接受。

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

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

这种方案业务层需要改造一下,将其强制性读主,相对改造难度较低。

不过这种方案相对于浪费了另一个数据库,增加主库的压力。

方案4:中间件路由法

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

这时流程如下:

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

延迟窗口内的读给打到主库,一定时间后,中间件认为延迟窗口的时间到了,主从同步复制完成了,后续请求可以打到从库,即不同时间打到不同库

方案5:缓存路由法

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

这时流程如下:

  1. 写请求发往主库,同时缓存记录操作的 key,缓存的失效时间设置为主从的延时
  2. 读请求首先判断缓存是否存在
    • 若存在,代表刚发生过写操作,读请求操作主库
    • 若不存在,代表近期没发生写操作,读请求操作从库

将redis的key的过期时间设置为主从的延时,这样就可以决定请求应该打到主库还是从库

5.主从复制需要的配置

主服务器:

1、开启二进制日志

2、配置唯一的server-id

3、获得master二进制日志文件名及位置

4、创建一个用于slave和master通信的用户账号

从服务器:

1、配置唯一的server-id

2、使用master分配的用户账号读取master二进制日志

3、启用slave服务

posted @ 2022-05-06 20:20  西*风  阅读(135)  评论(0编辑  收藏  举报