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:中间件路由法
这种方案需要使用一个中间件,所有数据库操作都先发到中间件,由中间件再分发到相应的数据库。
这时流程如下:
- 写请求,中间件将会发到主库,同时记录一下此时写请求的 key(操作表加主键等)
- 读请求,如果此时 key 存在,将会路由到主库
一定时间后(*经验值*),中间件认为主从同步完成,删除这个 key,后续读将会读从库
延迟窗口内的读给打到主库,一定时间后,中间件认为延迟窗口的时间到了,主从同步复制完成了,后续请求可以打到从库,即不同时间打到不同库
方案5:缓存路由法
这种方案与中间件的方案流程比较类似,不过改造成本相对较低,不需要增加任何中间件。
这时流程如下:
- 写请求发往主库,同时缓存记录操作的 key,缓存的失效时间设置为主从的延时
- 读请求首先判断缓存是否存在
- 若存在,代表刚发生过写操作,读请求操作主库
- 若不存在,代表近期没发生写操作,读请求操作从库
将redis的key的过期时间设置为主从的延时,这样就可以决定请求应该打到主库还是从库
5.主从复制需要的配置
主服务器:
1、开启二进制日志
2、配置唯一的server-id
3、获得master二进制日志文件名及位置
4、创建一个用于slave和master通信的用户账号
从服务器:
1、配置唯一的server-id
2、使用master分配的用户账号读取master二进制日志
3、启用slave服务