热搜:前端 nest neovim nvim

一文彻底搞懂MySql主从同步

lxf2023-05-28 18:15:01

这篇文章给大家带来了关于MySQL的相关知识,主要介绍MySQL的主同步及其功能原理等。感兴趣的朋友来看看。欢迎收藏学习!

1 引言

大家好,Mysql是最常用的数据库。以下是Mysql主从同步知识点分享,巩固Mysql的基础知识。如有错误,请纠正。

2 MySQL主同步概述

MySQL主要同步,即MySQL Replication,数据可以从一个数据库服务器同步到多个数据库服务器。MySQL数据库具有主从同步功能。通过配置,可以实现基于库和表结构的各种方案的主从同步。

Redis是一个高性能的内存数据库,但不是今天的主角;MySQL是一个基于磁盘文件的关系数据库。与Redis相比,读取速度较慢,但功能强大,可用于存储持久数据。在实际工作中,我们经常使用Redis作为缓存和MySQL。当有数据访问请求时,我们将首先从缓存中找到它。如果存在,我们将直接取出它。如果没有再访问数据库,将提高读取效率,降低后端数据库的访问压力。使用Redis缓存架构是高并发架构中非常重要的一部分。

一文彻底搞懂MySql主从同步

随着业务量的不断增长,数据库的压力将继续增加,缓存的频繁变化也取决于数据的查询结果,导致数据查询效率低、负载高、连接过多等问题。对于电子商务场景来说,经常有很多典型的读写场景。我们可以从架构和读写中分离MySQL,让主服务器(Master)从服务器处理写请求,从服务器(Slave)处理读取请求,可进一步提高数据库的并发处理能力。如下图:

一文彻底搞懂MySql主从同步

从上图可以看出,我们增加了两个从库,这两个从库可以抵御大量的阅读请求,分担主库的压力。从库将通过主从复制和主库中的持续同步数据,以确保从库中的数据与主库中的数据一致。

接下来,让我们来看看主从同步的作用,以及主从同步的具体实现。

3 主从同步的作用

一般来说,并不是所有的系统都需要从架构上设计数据库,因为架构本身有一定的成本。如果我们的目的是提高数据库的高并发访问效率,我们应该首先优化SQL语句和索引,充分发挥数据库的最大性能;其次,采用缓存策略,如使用Redis、缓存工具,如MongoDB,数据通过其高性能优势保存在内存数据库中,提高读取效率。最后,数据库采用主从架构进行读写分离。根据架构升级,系统的使用和维护成本逐渐增加。

言归正传,同步不仅可以提高数据库的吞吐量,还可以起到以下三个作用:

3.1 读写分离

我们可以通过复制来同步数据,然后通过读写分离来提高数据库的并发处理能力。简单地说,我们的数据被放在多个数据库中,其中一个是Master主库,另一个是Slave从库。当主库数据发生变化时,数据会自动同步到从库中,我们的程序可以从库中读取数据,即读写分离。电子商务的应用往往是“读多写少”,通过读写分离实现更高的并发访问。最初,所有的阅读和写作压力都由服务器承担,但现在有多个服务器共同处理阅读请求,以减轻主库的压力。此外,还可以平衡服务器的负载,使不同的阅读请求按照策略均匀地分配到不同的服务器中,使阅读更加顺畅。顺利阅读的另一个原因是减少了锁表的影响。例如,我们让主库负责写作。当主库出现锁时,不会影响从库的查询操作。

3.2 数据备份

主同步也相当于一种数据热备份机制,在主库正常运行下备份,不影响数据服务的提供。

3.3 高可用性

数据备份实际上是一种冗余机制。通过这种冗余方式,可以交换数据库的高可用性。当服务器出现故障、停机等不可用时,可以快速切换故障,使从库充当主库,保证服务的正常运行。您可以了解电子商务系统数据库的高可用性SLA指标。

4 主同步原理

说到主从同步原理,我们需要了解数据库中的一个重要日志文件,即Binlog二进制文件,它记录了更新数据库的事件。事实上,主从同步原理是基于Binlog进行数据同步。

在主从复制过程中,将基于三个线程进行操作,一个是binlog dump线程位于master节点上,另外两个线程分别是I/O线程和SQL线程,它们都位于slave节点上,如下图所示:

一文彻底搞懂MySql主从同步

结合以上图片,我们将了解主从复制的核心流程:

  • 当master节点收到一个写作请求时,这个写作请求可能是添加、删除和更改操作,此时将写作请求的更新操作记录到binlog日志中。

  • master节点将数据复制到slave节点,如图中的slave01节点和slave02节点所示。在这个过程中,每个slave节点都必须连接到master节点。当slave节点连接到master节点时,master节点将为每个slave节点创建一个binlog dump线程,用于向每个slave节点发送binlog日志。

  • binlog dump线程将读取master节点上的binlog日志,然后将binlog日志发送到slave节点上的I/O线程。当主库读取事件时,会在binglog上加锁,读取后再释放锁。

  • slave节点上的I/O线程接收到binlog日志后,将binlog日志首先写入当地的relaylog,并将binlog日志保存在relaylog中。

  • slave节点上的SQL线程将来读取relaylog中的binlog日志,并将其分析为具体的添加、删除和修改操作,并重做slave节点上的这些操作,以达到数据还原的效果,从而保证master节点和slave节点的数据一致性。

主同步数据内容实际上是二进制日志(Binlog),虽然它被称为二进制日志,但它实际上存储了一个又一个事件(Event),这些事件对应于数据库的更新操作,如INSERT、UPDATE、DELETE等。

此外,我们还需要注意的是,并不是所有版本的MySQL都默认打开了服务器的二进制日志。当主同步时,我们需要检查服务器是否打开了二进制日志。

二进制日志是一个文件,在网络传输过程中会有一些延迟,比如200ms,可能会导致用户从图书馆阅读的数据不是最新的数据,也会导致主同步中的数据不一致。比如我们更新一个记录,这个操作是在主库上完成的,而在很短的时间内,比如100ms,读取同一个记录。此时,数据从库中同步还没有完成,所以我们从库中读取的数据是一个旧数据。在这种情况下该怎么办?

5 如何解决主同步数据的一致性问题?

可以想象,如果我们想操作的数据存储在同一个数据库中,我们可以在更新数据时添加记录锁,这样在阅读时就不会出现数据不一致的情况。但此时,从库的作用是备份数据,不实现读写分离,分担主库的压力。

因此,我们还需要找到解决主同步中数据不一致的问题的方法,即解决主数据复制方法之间的问题。如果根据数据的一致性从弱到强进行划分,则有三种复制方法。

5.1 全同步复制

首先,全同步复制,即当主库执行事务时,所有从库必须执行事务,才能返回客户端;因此,虽然全同步复制数据一致性得到保证,但主库需要等待所有从库完成,性能相对较低。如下图所示:

一文彻底搞懂MySql主从同步

5.2 异步复制

异步复制,即当主库提交事物时,会通知binlog dump线程将binlog日志发送给从库,一旦binlog dump线程将binlog日志发送到从库后,主库将处理结果返回客户端,无需等到从库同步完成事务。

因为主库只要自己完成事务,就可以将处理结果返回客户端,而不用担心从库是否完成事务,这可能会导致主从数据短期不一致的问题。例如,如果刚刚插入主库的新数据立即从库中查询,则可能无法查询。

而且,当主库提交东西时,如果停机挂断,binlog可能还没有时间同步到库。此时,如果为了恢复故障而切换主节点,就会出现数据丢失的问题。因此,虽然异步复制性能高,但数据一致性最弱。

mysql主从复制,默认采用异步复制策略。

一文彻底搞懂MySql主从同步

5.3 半同步复制

MySQL5.5版本开始支持半同步复制。原理是客户端提交COMMIT后,不会直接将结果返回客户端,而是等待至少有一个Binlog从库中收到,写入中继日志,然后返回客户端。这样做的好处是提高了数据的一致性。当然,与异步复制相比,至少增加了网络连接的延迟,降低了主库写作的效率。

在MySQL5.7版本中还增加了一个rpl_semi_sync_master_wait_for_slave_count参数,我们可以设置需要响应的从库数量,默认为1,也就是说只要有从库响应,就可以返回客户端。如果增加这个参数,可以提高数据一致性的强度,但也会增加主库等待从库响应的时间。

一文彻底搞懂MySql主从同步

但是,半同步复制也存在以下问题:

  • 与异步复制相比,半同步复制的性能有所下降。与异步复制相比,不需要等待从库中收到数据的任何响应,而半同步复制需要等待至少一个从库中确认接收到binlog日志的响应,性能损失更大。
  • 可以配置主库等待从库响应的最大时间。如果超过配置时间,半同步复制就会变成异步复制,也会出现异步复制的问题。
  • 在MySQL 5.7.在之前的版本中,半同步复制存在幻读问题。

当主库成功提交事物并等待从库确认时,此时还没有时间将处理结果返回客户端,但由于主库存储引擎已提交事务,其他客户端可以从主库读取数据。

但是,如果下一秒主库突然挂断,此时正好是下一个请求,因为主库挂断了,请求只能切换到从库,因为从库还没有从主库同步数据,所以从库当然不能读取数据,与上一秒读取数据的结果相比,导致了幻读现象。

5.4 增强半同步复制

增强半同步复制,是mysqll 5.7.2后版本对半同步复制进行了改进,原则上几乎是一样的,主要是为了解决幻读问题。

主库配有参数 rpl_semi_sync_master_wait_point = AFTER_SYNC 之后,在主库存储引擎提交事务之前,必须在提交事务之前收到从库数据同步完成的确认信息,以解决幻读问题。参考下图:

一文彻底搞懂MySql主从同步

6 总结

通过以上内容,我们了解了Mysql数据库的主从同步。如果你的目标只是数据库的高并发性,那么你可以先从 SQL 优化、索引和 Redis 在这些方面考虑优化,如缓存数据,然后考虑是否采用主从架构。

在主从架构的配置中,如果要采取读写分离的策略,可以自己编写程序,也可以通过第三方中间件实现。

编写自己程序的好处是相对独立。我们可以判断哪些查询是从图书馆执行的。根据实时要求高的要求,我们还可以考虑哪些查询可以在主图书馆执行。同时,程序直接连接到数据库,减少了中间件层,可以减少一些性能损失。

而采用中间件的方法具有明显的优点,功能强大,使用简单。但是,由于客户端和数据库之间增加了中间件层,会出现一些性能损失。同时,商业中间件价格高,有一定的学习成本。此外,我们还可以考虑使用一些优秀的开源工具,比如 MaxScale。它是 MariaDB 开发的 MySQL 数据中间件。例如,在下图中,使用 MaxScale作为数据库的代理,通过路由转发完成读写分离。我们也可以同时使用它 MHA 工具作为强一致的主切换工具,从而完成 MySQL的高可用架构。

一文彻底搞懂MySql主从同步

推荐学习:MySQL视频教程

以上是一篇完全了解Mysql同步的文章,更多请关注AdminJS的其他相关文章!