(面经总结)一篇文章带你深入学习 Mysql 中的主从复制

一、Mysql 的主从复制

简单来说是让一台MySQL服务器去复制另一台MySQL的数据,使两个服务器的数据保持一致

通过复制功能,构建一个或者多个从库,可以提高数据库的高可用性、可扩展性,同时实现负载均衡。

当主库发生故障时,可以快速的切到其某一个从库,并将该从库提升为主库,因为数据都一样,所以不会影响系统的运行;

当MySQL服务器需要扛住更多的读请求时,可以把读请求的流量分流到各个从库上去,写请求则转发给主库,形成读写分离的架构,来提供更好的读扩展和请求的负载均衡。

二、主从同步的实现步骤

(1)主服务器(master)将对数据的操作记录到二进制日志文件(Binary log)中,也就是说,在每个事务更新数据完成之前,mster在日志里记录这些改变,mysql将事务串行地写入二进制文件中,在事件写入二进制日志完成后,master通知存储引擎提交事务,提交好事务后,就会进入第二步,需要补充一点的是,我们对数据的一次操作就称为一次二进制日志事件,也就是Binary log event

(2)Slave将master的Binary log拷贝到它的中继日志(Relay log)中,也就是Slave会首先开启一个工作线程(I/O thread),I/O线程在master上打开一个普通的连接,做Binary log的拷贝,从master的二进制日志文件中读取事件,如果已经跟上了master,就会睡眠并等待master产生新的事件,I/O线程然后将这些事件写入中继日志中

(3)Slave重做中继日志事件,SQL线程从中继日志中读取事件,并重放其中的事件,更新Slave中的数据,使其与Master中的数据一致。
在这里插入图片描述

三、复制方式

1. 异步复制

首先就是异步,这也是MySQL默认的方式。

在异步复制下,主库不会主动的向从库发送消息,而是等待从库的I/O线程建立连接,然后主库创建binlog dump线程,把binlog event发送给I/O线程,流程如下图。
在这里插入图片描述
主库在执行完自己的事务、记录完binlog之后就会直接返回,不会与客户端确认任何结果。然后后续由binlog dump线程异步的读取binlog,然后发送给从库。

处理请求和主从复制是两个完全异步化的过程

2. 同步复制

同步模式则是,主库执行一个事务,那么主库必须等待所有的从库全部执行完事务返回commit之后才能给客户端返回成功,

在这里插入图片描述
值得注意的是,主库会直接提交事务,而不是等待所有从库返回之后再提交。MySQL只是延迟了对客户端的返回,并没有延后事务的提交。

同步模式用脚趾头想知道性能会大打折扣,它把客户端的请求和主从复制耦合在了一起,如果有某个从库复制线程执行的慢,那么对客户端的响应也会慢很多。

3. 半同步复制

半同步相对于同步的区别在于,同步需要等待所有的从库commit,而半同步只需要一个从库commit就可以返回了。

如果超过默认的时间仍然没有从库commit,就会切换为异步模式再提交。客户端也不会一直去等待了。
在这里插入图片描述
因为即使后面主库宕机了,也能至少保证有一个从库节点是可以用的,此外还减少了同步时的等待时间。

四、主从复制的模型

1. 一主多从

这是最简单的模型,特别适合少量写、大量读的情况。读请求被分到了各个从库上,有效的帮主库分散了压力,能够提升读并发。

当然,你也可以只是把从库当成一个灾备库,除了主从复制之外,没有其他任何的请求和数据传输。

甚至你可以把其中一个备库作为你的预发环境的数据库,当然,这说到底还是直接动了生产环境的数据库,是一种过于理想的用途,因为这还涉及到生产环境数据库的数据敏感性。不是所有人都能够接触到的,需要有完善的权限机制。
在这里插入图片描述
值得注意的是,如果有n个从库,那么主库上就会有n个binlog dump线程。如果这个n比较大的话在复制的时候可能会造成主库的性能抖动。所以在从库较多的情况下可以采用级联复制。

2. 级联复制

级联复制用大白话说就是套娃。

本来从库B、C、D、E、F、G都是复制的主库A,但是现在由于A的压力比较大,就不这么干了,调整成了如下的模式。

B、C复制A
D、E复制B
F、G复制C

在这里插入图片描述
这就叫级联复制,开启疯狂套娃模式。你甚至会觉得这种套娃很眼熟,在Redis主从复制中也可以采用级联模式, slave去复制另一个slave。

级联复制的好处在于很大程度上减轻了主库的压力,主库只需要关心与其有直接复制关系的从库,剩下的复制则交给从库即可。相反,由于是这种层层嵌套的关系,如果在较上层出现了错误,会影响到挂在该服务器下的所有子库,这些错误的影响效果被放大了。

3. 主主复制

顾名思义,就是两个主库相互复制,客户端可以对任意一台主库进行写操作。任何一台主库服务器上的数据发生了变化都会同步到另一台服务器上去。有点类似于Eureka Server的双节点模式,两个注册中心相互注册。这样一来,任何一台挂了都不会对系统产生影响。

而且主主复制可以打破数据库性能瓶颈,一个很酷的功能——横向扩展。为什么说很酷呢,如果DB能做到横向扩展,那很多被数据库并发所限制的瓶颈都可以被突破,然而…

但是主主复制其实并不可靠,两边的数据冲突的可能性很大。例如复制停止了,系统仍然在向两个主库中写入数据,也就是说一部分数据在A,另一部分的数据在B,但是没有相互复制,且数据也不同步了。要修复这部分数据的难度就会变得相当大。

所以我认为双主的更多的意义在于HA,而不是负载均衡。

4. 主、被动的主主复制

同样还是双主的结构,但是区别在于其中一台是只读的被动服务器,客户端不会向该库进行写操作

可以在不停止服务的情况下去做数据库的结构更新,其次可以在主库发生故障的情况下,快速的切换,保证数据库的HA。

五、主从复制的延时

主从复制的延时危害:可能在业务表现上表现为读写不一致(新增/修改数据查不到)

原因分析:
(1)主库大量的写请求操作,在短时间产生了大量的binlog。这些操作需要全部同步到从库,并且执行,因此产生了主从的数据复制延时。

解决办法:提高从服务器的并行度
Mysql5.7以上:支持并行复制

(2)主库执行大事务,需要的耗时长,当大事务记录入binlog并同步到从库之后,从库执行这个事务的操作耗时也非常长,这段时间,就会产生主从复制延时。

解决办法:拆分大事务语句到若干小事务中,这样能够进行及时提交,减小主从复制延时。

(3)如果主库和从库使用了不同的计算资源和存储资源,或者使用了不同的内核调教参数,可能会造成主从不一致。

解决办法:考虑尽量统一DB机器的配置(包括硬件及选项参数)

(4)从库自身压力很大,更不上主库的更新速度,也会产生主从复制延时(CPU负载,IO利用率过高)

解决办法:降低从库的压力,打散读请求

参考

【1】https://www.huaweicloud.com/articles/67692bcf85863b4782e3270f18ee2070.html
【2】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值