1 引言
大家好,Mysql 是大家最罕用的数据库,上面为大家带来 mysql 主从同步知识点的分享,以便坚固 mysql 基础知识,如有谬误,还请各位大佬们斧正。
2 MySql 主从同步概述
MySQL 主从同步,即 MySQL Replication,能够实现将数据从一台数据库服务器同步到多台数据库服务器。MySQL 数据库自带主从同步性能,通过配置,能够实现基于库、表构造的多种计划的主从同步。
Redis 是一种高性能的内存数据库,但不是明天的配角;MySQL 是基于磁盘文件的关系型数据库,相比于 Redis 来说,读取速度会慢一些,然而功能强大,能够用于存储长久化的数据。在理论工作中,咱们常将 Redis 作为缓存与 MySQL 配合来应用,当有数据拜访申请的时候,首先会从缓存中进行查找,如果存在就间接取出,如果不存在再拜访数据库,这样就晋升了读取的效率,也缩小了后端数据库的拜访压力。应用 Redis 这种缓存架构是高并发架构中十分重要的一环。
随着业务量的一直增长,数据库的压力会一直变大,缓存的频繁变更也强依赖于数据的查问后果,导致数据查问效率低,负载很高,连贯过多等问题。对于电商场景来说,往往存在很多典型的读多写少场景,咱们能够对 MySQL 做主从架构并且进行读写拆散,让主服务器(Master)解决写申请,从服务器(Slave)解决读申请,这样能够进一步晋升数据库的并发解决能力。如下图:
上图中,能够看到,咱们减少了 2 个从库,这 2 个从库能够一起抗下大量的读申请,分担主库压力。从库会通过主从复制,从主库中一直的同步数据,以此来保障从库的数据和主库数据的统一。接下来,咱们看看主从同步有哪些作用,以及主从同步具体是怎么实现的。3 主从同步的作用
3 主从同步的作用
一般来说,不是所有的零碎都须要对数据库进行主从架构的设计,因为架构自身是有肯定老本的,如果咱们的目标在于晋升数据库高并发拜访的效率,那么咱们首先应该优化 SQL 语句及索引,充分发挥数据库的最大性能;其次是采纳缓存的策略,如应用 Redis、Magodb 等缓存工具,通过其高性能的劣势把数据保留在内存数据库中,晋升读取的效率,最初才是对数据库采纳主从架构,进行读写拆散。零碎的应用和保护老本是依据架构的降级逐步升高的。
言归正传,主从同步不仅能够晋升数据库的吞吐量,还有以下三个方面的作用:
3.1 读写拆散
咱们能够通过主从复制的形式来同步数据,而后通过读写拆散晋升数据库的并发解决能力。简略来说就是咱们的数据被放在了多个数据库中,其中一个是 Master 主库,其余的是 Slave 从库。当主库数据变动时,会主动将数据同步到从库中,而咱们程序能够从从库读取数据,也就是采纳读写拆散的形式。电商的利用往往是“读多写少”,采纳读写拆散就实现了更高的并发拜访。本来所有的读写压力都由一台服务器承当,当初有多个服务器独特解决读申请,缩小了对主库的压力。另外还能够对从服务器进行负载平衡,让不同的读申请依照策略平均的调配到不同的从服务器中,让读取更加顺畅。读取顺畅的另一个起因,就是缩小了锁表的影响,比方咱们让主库负责写,当主库呈现写锁的时候,不会影响到从库的查问操作。
3.2 数据备份
主从同步也相当于是一种数据热备份机制,在主库失常运行下进行备份,不影响提供数据服务。
3.3 高可用性
数据备份理论就是一种冗余的机制,通过这种冗余的形式能够换取数据库的高可用性,当服务器呈现故障、宕机等无可用的状况下,能够迅速进行故障切换,让从库充当主库,保障服务失常运行。大家能够理解下电商零碎数据库高可用 SLA 指标。
4 主从同步的原理
说到主从同步的原理,咱们就须要理解在数据库中的一个重要日志文件,就是 Binlog 二进制文件,它记录了对数据库进行更新的事件,事实上主从同步的原理就是基于 Binlog 进行数据同步的。
在主从复制的过程中,会基于三个线程来操作,一个是 binlog dump 线程,位于 master 节点上,另外两个线程别离是 I / O 线程和 SQL 线程,它们都别离位于 slave 节点上,如下图:
联合以上图片,咱们一起来理解主从复制的外围流程:
- 当 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 中,relaylog 中就保留了 binlog 日志。
- slave 节点上的 SQL 线程,会来读取 relaylog 中的 binlog 日志,将其解析成具体的增删改操作,把这些在 master 节点上进行过的操作,从新在 slave 节点上也重做一遍,达到数据还原的成果,这样就能够保障 master 节点和 slave 节点的数据一致性了。
主从同步的数据内容其实是二进制日志(Binlog),它尽管叫二进制日志,实际上存储的是一个又一个的事件(Event),这些事件别离对应着数据库的更新操作,比方 INSERT、UPDATE、DELETE 等。
另外咱们还须要留神的是,不是所有版本的 MySQL 都默认开启了服务器的二进制日志,在进行主从同步的时候,咱们须要先查看服务器是否曾经开启了二进制日志。
二进制日志,它是一个文件,在进行网络传输的过程中就肯定会存在一些提早,比方 200ms,这样就可能造成用户在从库上读取的数据不是最新的数据,也就会造成主从同步中的数据不统一的状况产生。比方咱们对一条记录进行更新,这个操作是在主库上实现的,而在很短的工夫内,比方 100ms,又对同一个记录进行读取,这时候从库还没有实现数据的同步,那么,咱们通过从库读取到的数据就是一条旧的数据。这种状况下该怎么办呢?
5 如何解决主从同步的数据一致性问题
能够设想下,如果咱们想要操作的数据都存储在同一个数据库中,那么对数据进行更新的时候,能够对记录进行加写锁,这样在读取的时候就不会产生数据不统一的状况了。但这时从库的作用就是备份数据,没有做到读写拆散,分担主库的压力。
因而咱们还须要想方法,在进行读写拆散的时候,解决主从同步中数据不统一的问题,也就是解决主从之间数据复制形式的问题,如果依照数据一致性从弱到强来进行划分,有以下三种复制形式。
5.1 全同步复制
首先,全同步复制,就是当主库执行完一个事务之后,要求所有的从库也都必须执行完该事务,才能够返回处理结果给客户端;因而,尽管全同步复制数据一致性失去保障了,然而主库实现一个事物须要期待所有从库也实现,性能就比拟低了。
如下图:
5.2 异步复制
而异步复制,就是当主库提交事物后,会告诉 binlog dump 线程发送 binlog 日志给从库,一旦 binlog dump 线程将 binlog 日志发送给从库之后,不须要等到从库也同步实现事务,主库就会将处理结果返回给客户端。
因为主库只管本人执行完事务,就能够将处理结果返回给客户端,而不必关怀从库是否执行完事务,这就可能导致短暂的主从数据不统一的问题了,比方刚在主库插入的新数据,如果马上在从库查问,就可能查问不到。
而且,当主库提交事物后,如果宕机挂掉了,此时可能 binlog 还没来得及同步给从库,这时候如果为了复原故障切换主从节点的话,就会呈现数据失落的问题,所以异步复制尽管性能高,但数据一致性上是最弱的。mysql 主从复制,默认采纳的就是异步复制这种复制策略。
5.3 半同步复制
MySQL5.5 版本之后开始反对半同步复制的形式。原理是在客户端提交 COMMIT 之后不间接将后果返回给客户端,而是期待至多有一个从库收到了 Binlog,并且写入到中继日志中,再返回给客户端。这样做的益处就是进步了数据的一致性,当然相比于异步复制来说,至多多减少了一个网络连接的提早,升高了主库写的效率。
在 MySQL5.7 版本中还减少了一个 rpl_semi_sync_master_wait_for_slave_count 参数,咱们能够对须要响应的从库数量进行设置,默认为 1,也就是说只有有一个从库进行了响应,就能够返回给客户端。如果将这个参数调大,能够晋升数据一致性的强度,但也会减少主库期待从库响应的工夫。
然而,半同步复制也存在以下几个问题:
- 半同步复制的性能,相比异步复制而言有所降落,相比于异步复制是不须要期待任何从库是否接管到数据的响应,而半同步复制则须要期待至多一个从库确认接管到 binlog 日志的响应,性能上是损耗更大的。
- 主库期待从库响应的最大时长是能够配置的,如果超过了配置的工夫,半同步复制就会变成异步复制,那么,异步复制的问题同样也就会呈现了。
- 在 MySQL 5.7.2 之前的版本中,半同步复制存在着幻读问题的。
当主库胜利提交事物并处于期待从库确认的过程中,这个时候,从库都还没来得及返回处理结果给客户端,但因为主库存储引擎外部曾经提交事务了,所以,其余客户端是能够到从主库中读到数据的。
然而,如果下一秒主库忽然挂了,此时正好下一次申请过去,因为主库挂了,就只能把申请切换到从库中,因为从库还没从主库同步完数据,所以,从库中当然就读不到这条数据了,和上一秒读取数据的后果比照,就造成了幻读的景象了。
5.4 加强半同步复制
加强半同步复制,是 mysql 5.7.2 后的版本对半同步复制做的一个改良,原理上简直是一样的,次要是解决幻读的问题。
主库配置了参数 rpl_semi_sync_master_wait_point = AFTER_SYNC 后,主库在存储引擎提交事务前,必须先收到从库数据同步实现的确认信息后,能力提交事务,以此来解决幻读问题。参考下图:
6 总结
通过上述内容,咱们理解了 Mysql 数据库的主从同步,如果你的指标仅是数据库的高并发,那么能够先从 SQL 优化,索引以及 Redis 缓存数据等这些方面来思考优化,而后再思考是否采纳主从架构的形式。
在主从架构的配置中,如果想要采取读写拆散的策略,咱们能够本人编写程序,也能够通过第三方的中间件来实现。
本人编写程序的益处就在于比拟自主,咱们能够本人判断哪些查问在从库上来执行,针对实时性要求高的需要,咱们还能够思考哪些查问能够在主库上执行。同时程序间接连贯数据库,缩小了中间件层,能够缩小一些性能损耗。
而采纳中间件的办法有很显著的劣势,功能强大,应用简略。但因为在客户端和数据库之间减少了中间件层会有一些性能损耗,同时商业中间件价格较高,有肯定学习老本。另外,咱们也能够思考采纳一些优良的开源工具,比方 MaxScale。它是 MariaDB 开发的 MySQL 数据中间件。比方在下图中,应用 MaxScale 作为数据库的代理,通过路由转发实现了读写拆散。同时咱们也能够应用 MHA 工具作为强统一的主从切换工具,从而实现 MySQL 的高可用架构。