MySQL主从篇:死磕主从复制中数据同步原理与优化

一、主从复制架构概述

   不论任何技术栈,但凡一提高可用、高性能、高稳定这些词汇,必然会牵扯到集群、主从架构的概念,如MQ、Redis、ES、MongoDB、Zookeeper.....任何技术栈中都会有,而MySQL中同样不例外,官方也提供了主从架构的支持,通过调整多个MySQL节点的配置信息,即可将一个节点的数据同步给另一个或多个节点,但这种方式同步的是所有数据!

有人也许会疑惑:为什么要同步所有数据呀?难道不能对数据作分片,不同的节点同步不同的数据嘛?这实际上属于历史遗留性的问题,在早些年由于分布式技术还未完善,所以大多技术栈在设计高可用方案时,基本上都选用主从架构,也就是各节点之间都同步所有数据,从而对外提供高可用的保障。

主从架构中必须有一个主节点,以及一个或多个从节点,所有的数据都会先写入到主,接着其他从节点会复制主节点上的增量数据,从而保证数据的最终一致性,使用主从复制方案,可以进一步提升数据库的可用性和性能:

  • ①在主节点宕机或故障的情况下,从节点能自动切换成主节点的身份,从而继续对外提供服务。
  • ②提供数据备份的功能,当主节点的数据发生损坏时,从节点中依旧保存着完整数据。
  • ③可以基于主从实现读写分离,主节点负责处理写请求,从节点处理读请求,进一步提升性能。

但无论任何技术栈的主从架构,都会存在致命硬伤,同时也会存在些许问题需要解决:

  • ①硬伤:木桶效应,一个主从集群中所有节点的容量,受限于存储容量最低的哪台服务器。
  • ②数据一致性问题:由于同步复制数据的过程是基于网络传输完成的,所以存储延迟性。
  • ③脑裂问题:从节点会通过心跳机制,发送网络包来判断主机是否存活,网络故障情况下会产生多主。

上述提到的三个问题中,第一个问题只能靠加大服务器的硬件配置解决,第二个问题相对来说已经有了很好的解决方案(后续讲解),第三个问题则是部署方式决定的,如果将所有节点都部署在同一网段,基本上不会出现集群脑裂问题。

上面简单了解了主从复制架构的一些基本概念后,接着来聊一聊MySQL中的主从复制。

二、MySQL中的主从复制技术

   MySQL本身提供了主从复制的技术支持,所以无需通过第三方技术来协助实现,MySQL数据复制的过程就是基于该日志完成的,但MySQL复制数据的过程并非同步,而是异步的方式,啥是同步、异步方式呢?如下:


上图中,上面是同步复制的过程,也就是当主节点接收到一个客户端的写请求后,先会往自身写入数据,接着会去要求其他从节点也写入数据,当从节点的数据写入完成后,最终才会向客户端返回写入成功。

而异步复制的过程恰恰相反,当主节点接收到一个客户端的写请求后,先会往自身写入数据,自身数据写入成功后,就会立马向客户端返回写入成功的信息,对于从节点的数据,会在其他的时间内再异步复制过去。

对比同步复制和异步复制的过程,显然同步复制的过程极其影响效率,因为需要等到所有从节点写完之后才返回数据。而异步复制的过程则快很多了,基本和MySQL单机版的写入效率差距不大,只要主节点自身写入成功,则立马返回写入成功,性能自然会快很多,而MySQL主从的数据复制,就是基于这种异步方案实现。

有人也许会好奇:同步复制方案效率那么低,一般没有谁用吧?实则不然,比如大名鼎鼎的Zookeeper中,就采用的是同步复制方案,这是为什么呢?因为同步复制方案能够确保数据100%不丢失,和数据的强一致性。如果采用异步复制方案,那么当一个数据写入后,主节点立马宕机或故障了,从机顶替上线,这时的从机是不一定有最新数据的,而同步方案则不需要担心这个问题(Zookeeper采用的是半同步模式,后续再展开细聊~)。

2.1、MySQL数据同步的原理

   前面搞清楚了MySQL同步数据的方式,接着聊一聊它的同步原理,前面简单提到过一句:MySQL是基于它自身的Bin-log日志来完成数据的异步复制,因为Bin-log日志中会记录所有对数据库产生变更的语句,包括DML数据变更和DDL结构变更语句,数据的同步过程如下:


上述即是主从同步数据的原理图,但在讲解之前先来了解一下两种数据同步的方式:

  • 主节点推送:当主节点出现数据变更时,主动向自身注册的所有从节点推送新数据写入。
  • 从节点拉取:从节点定期去询问一次主节点是否有数据更新,有则拉取新数据写入。

MySQL究竟采用的是什么方式呢?其实是「从拉」的方案,但对其稍微做了一些优化,传统的「从拉」方案是需要从节点一直与主节点保持长连接,从节点定时或持续性的对主节点做轮询,查看主机的数据是否发生了变更,而MySQL的数据同步原理如下:

  • ①客户端将写入数据的需求交给主节点,主节点先向自身写入数据。
  • ②数据写入完成后,紧接着会再去记录一份Bin-log二进制日志。
  • ③配置主从架构后,主节点上会创建一条专门监听Bin-log日志的log dump线程。
  • ④当log dump线程监听到日志发生变更时,会通知从节点来拉取数据。
  • ⑤从节点会有专门的I/O线程用于等待主节点的通知,当收到通知时会去请求一定范围的数据。
  • ⑥当从节点在主节点上请求到一定数据后,接着会将得到的数据写入到relay-log中继日志。
  • ⑦从节点上也会有专门负责监听relay-log变更的SQL线程,当日志出现变更时会开始工作。
  • ⑧中继日志出现变更后,接着会从中读取日志记录,然后解析日志并将数据写入到自身磁盘中。

阅读上述流程后,相信大家能感受出MySQL主从复制时做的优化,在主从数据同步的过程中,从节点并不会无限制的询问主机,这样实在太影响效率了,在MySQL中引入了惰性的思想,只有当主节点真正出现数据变更时,才会通知从节点拉取数据!

2.2、从节点拉取的数据到底是什么格式?

   前面从整体角度出发,简单讲述了主从同步数据的过程,但从节点复制的数据到底是什么格式的呢?这里要根据主节点的Bin-log日志格式来决定,它会有三种格式,如下:

  • Statment:记录每一条会对数据库产生变更操作的SQL语句(默认格式)。
  • Row:记录具体出现变更的数据(也会包含数据所在的分区以及所位于的数据页)。
  • MixedStatment、Row的结合版,可复制的记录SQL语句,不可复制的记录具体数据。

一般在搭建主从架构时&#x

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值