当前位置: 首页 > 科技观察

MySql主从同步简介

时间:2023-03-13 11:51:49 科技观察

大家好,Mysql是大家最常用的数据库。下面是mysql主从同步知识点的分享,巩固mysql的基础知识。如有错误,请指正。一、MySql主从同步概述MySQL主从同步,即MySQLReplication,可以将数据从一台数据库服务器同步到多台数据库服务器。MySQL数据库自带主从同步功能。配置后可以实现基于数据库和表结构的各种方案的主从同步。Redis是一个高性能的内存数据库,但它不是今天的主角;MySQL是一个基于磁盘文件的关系型数据库。与Redis相比,读取速度会慢一些,但是功能强大,可以用来存储持久化的数据。在实际工作中,我们经常会结合MySQL使用Redis作为缓存。当有数据访问请求时,会先从缓存中查找。如果存在,则直接取出。如果不存在,则访问数据库,这样可以提高读取效率,也可以减轻后端数据库的访问压力。使用Redis这种缓存架构,是高并发架构中非常重要的一环。随着业务量的不断增长,数据库的压力会不断增大,而缓存的频繁变化也对数据的查询结果产生了强烈的依赖,导致数据查询效率低、负载高、和太多的联系。对于电商场景,往往有很多读多写少的典型场景。我们可以采用MySQL为主从架构,读写分离,让主服务器(Master)处理写请求,从服务器(Slave)处理读请求。这样可以进一步提高数据库的并发处理能力。如下图所示:在上图中,我们可以看到我们添加了2个从库,可以共同抵抗大量的读请求,分担主库的压力。从库会通过主从复制不断从主库同步数据,保证从库中的数据与主库中的数据一致。下面我们就来看看主从同步的作用以及它是如何实现的。2、主从同步的作用一般来说,并不是所有系统都需要为数据库设计主从架构,因为架构本身是有一定成本的。如果我们的目的是提高高并发访问数据库的效率,那么我们首先应该优化SQL语句和索引,以充分发挥数据库的最大性能;其次采用缓存策略,比如使用Redis、Magodb等缓存工具,通过其高性能优势将数据保存在内存数据库中,提高读取效率,最后采用主从架构数据库读写分离。系统的使用和维护成本随着架构的升级而逐渐增加。言归正传,主从同步不仅可以提高数据库的吞吐量,还有以下三个方面:1.读写分离我们可以通过主从复制来同步数据,进而提高数据库的并发处理能力数据库通过读写分离。简单的说就是我们的数据放在多个数据库中,其中一个是Master主库,其余的都是Slave从库。当主库中的数据发生变化时,数据会自动同步到从库中,我们的程序可以从从库中读取数据,即采用读写分离的方式。电商应用往往是“读多写少”,利用读写分离实现更高的并发访问。本来所有的读写压力都由一台服务器承担,现在多台服务器共同处理读请求,减轻了主库的压力。另外,还可以对从服务器进行负载均衡,让不同的读请求按照策略平均分配到不同的从服务器上,让读更流畅。读取流畅的另一个原因是减少锁表的影响。比如我们让主库负责写,当主库有写锁的时候,是不会影响从库的查询操作的。2、数据备份。主从同步也相当于一种数据热备份机制。备份在主库正常运行的情况下进行,不影响数据服务的提供。3、高可用数据备份其实是一种冗余机制。通过这种冗余的方式,可以换取数据库的高可用。当服务器出现故障、宕机等情况时,从库充当主库,保证服务的正常运行。可以了解电商系统数据库的高可用SLA指标。3、主从同步原理说到主从同步原理,我们需要了解数据库中一个重要的日志文件,就是Binlog二进制文件,它记录了更新数据库的事件。其实主从同步的原理就是基于Binlog来进行数据同步的。在主从复制的过程中,会基于三个线程进行操作,一个是binlogdump线程,位于master节点上,另外两个线程是I/O线程和SQL线程,分别是分别位于从节点上,如下图:结合上图,我们来了解一下主从复制的核心流程:当主节点收到写请求时,写请求可能是增删改查操作,此时,写请求的所有更新操作都会记录在binlog日志中。主节点会将数据复制到从节点,如图中的slave01节点和slave02节点。在这个过程中,每个从节点都必须先连接到主节点。当slave节点连接到master节点后,master节点会为每个slave节点创建一个binlogdump线程,将binlog日志发送给各个slave节点。binlogdump线程会读取master节点上的binlog日志,然后将binlog日志发送给slave节点上的I/O线程。主库在读取事件时,对Binglog进行加锁,读取完成后释放锁。从节点上的I/O线程收到binlog日志后,会先将binlog日志写入本地relaylog,binlog日志保存在relaylog中。从节点上的SQL线程会读取relaylog中的binlog日志,解析成具体的增删改查操作,在从节点上再次重做对主节点执行的操作,达到数据恢复的效果,所以保证主从节点之间的数据一致性。主从同步的数据内容其实就是二进制日志(Binlog)。虽然它被称为二进制日志,但它实际上是一个接一个地存储事件。这些事件对应着数据库的更新操作,如INSERT、UPDATE、DELETE等。另外,我们还需要注意,并不是所有版本的MySQL都默认开启了服务器的二进制日志。在进行主从同步时,我们需要检查服务器是否开启了二进制日志。二进制日志,它是一个文件,在网络传输的过程中肯定会有一些延迟,比如200ms,这可能会导致用户从库中读取的数据不是最新的数据,也会造成主从同步出现数据不一致。比如我们更新一条记录,这个操作是在主库上完成的,在很短的时间内,比如100ms,我们再次读取同一条记录。此时从库还没有完成数据同步,那么,我们从库中读取的数据就是旧数据了。遇到这种情况怎么办?4、如何解决主从同步的数据一致性问题。想象一下,如果我们要操作的数据都存储在同一个数据库中,那么在更新数据的时候,可以给记录加上写锁,这样在读的时候就不会出现数据不一致的情况。但是此时从库的作用是备份数据,并没有实现读写分离,分担主库的压力。所以,我们还是需要想办法解决主从同步在进行读写分离时数据不一致的问题,也就是解决主从之间的数据复制问题。如果按照数据一致性从弱到强来划分,有以下三种复制方式。1、全同步复制首先,全同步复制是指主库执行完一个事务后,所有从库也必须执行完该事务,然后才将处理结果返回给客户端;因此,全量同步复制虽然数据一致,性能有保证,但是主库需要等待所有从库完成一个事务,性能比较低。如下图所示:2.异步复制异步复制是指主库提交事务时,会通知binlogdump线程将binlog日志发送到从库。binlogdump线程一旦将binlog日志发送到从库,就不需要等到从库也同步完成事务后,主库才会将处理结果返回给客户端。因为主库只需要自己执行事务,就可以将处理结果返回给客户端,而无需关心从库是否已经完成事务,这可能会造成短期的主从数据不一致,比如数据刚刚插入主库。如果立即从数据库中查询新数据,则可能查询不到。而且主库提交东西的时候,如果机器挂了,此时binlog可能还没有同步到从库。这时候如果切换主从节点恢复failover,就会出现数据丢失的问题,所以异步复制虽然性能高,但是数据一致性是最弱的。MySQL主从复制默认采用异步复制策略。3.半同步复制MySQL5.5开始支持半同步复制。原理是client提交COMMIT后,结果不是直接返回给client,而是等待至少一个slave接收到Binlog,写入relaylog,再返回给client。这样做的好处是提高了数据的一致性。当然,与异步复制相比,至少多了一个网络连接延迟,降低了主库的写入效率。在MySQL5.7版本中,增加了一个rpl_semi_sync_master_wait_for_slave_count参数。我们可以设置需要响应的从库数量。默认为1,表示只要有一个从库响应,就可以返回给客户端。如果增加这个参数,可以提高数据一致性的强度,但是也会增加主库等待从库响应的时间。但是,半同步复制也存在以下问题:半同步复制的性能相比异步复制有所下降。与异步复制相比,不需要等待库的任何响应来接收数据,而半同步复制需要等待至少一个库的响应来确认收到binlog日志,成本更高性能方面。可以配置主库等待从库响应的最长时间。如果超过配置的时间,半同步复制就会变成异步复制,那么异步复制的问题也会出现。MySQL5.7.2之前的版本存在半同步复制幻读的问题。当主库成功提交交易,正在等待从库确认的过程中,此时从库还没有来得及将处理结果返回给客户端,但是由于主库存储引擎已经已经提交了交易,其他客户端可以从主库读取数据。但是,如果下一秒主库突然挂了,下一个请求就在这个时候到来。因为主库宕机了,请求只能切换到从库,因为从库还没有从主库同步数据,所以,当然不能从库中读取到这条数据。与上一秒读取数据的结果相比,造成幻读现象。4、增强型半同步复制增强型半同步复制是mysql5.7.2以后版本对半同步复制的改进。原理差不多,主要是解决幻读问题。主库配置参数rpl_semi_sync_master_wait_point=AFTER_SYNC后,在存储引擎提交事务前,主库必须收到存储引擎提交事务前数据同步完成的确认,解决幻读问题.参考下图:五、总结通过以上内容,我们了解了Mysql数据库的主从同步。如果你的目标只是数据库的高并发,可以先考虑SQL优化、索引、Redis缓存数据等方面。优化,再考虑是否采用主从架构。在主从架构的配置上,如果我们要采用读写分离策略,可以自己写程序,也可以通过第三方中间件来实现。自己写程序的好处是比较独立。我们可以判断哪些查询是在从库上执行的。对于实时性要求高的,我们还可以考虑在主库上执行哪些查询。同时,程序直接连接数据库,减少了中间件层,减少了一些性能损失。使用中间件的方法具有明显的优势,如功能强大,使用简单。但是由于在客户端和数据库之间增加了中间件层,所以会有一定的性能损耗。同时,商业中间件的价格比较高,有一定的学习成本。另外,我们也可以考虑使用一些优秀的开源工具,比如MaxScale。是MariaDB开发的一款MySQL数据中间件。比如下图中,MaxScale作为数据库的代理,通过路由转发完成读写分离。同时,我们也可以使用MHA工具作为强一致性的主从切换工具来完成MySQL的高可用架构。