MySQL高可用架构(一)

时间:2021-07-16 01:09:55

本文档介绍了MySQL的一些高可用方案,从3个角度说明了MySQL的高可用类型,中间件解决方案,主从管理组件实现方案,原生的集群解决方案(MGR+PXC),MySQL的所有解决方案都是基于主从复制,本文档会优先介绍一下MySQL的主从同步类型。

复制类型

按照MySQL 的复制特点,大体上可以分为三种类别:

1 、异步复制;

对于异步复制,主库将事务Binlog 事件写入到Binlog 文件中,此时主库只会通知一下Dump 线程发送这些新的Binlog ,然后主库就会继续处理提交操作,而此时不会保证这些Binlog 传到任何一个从库节点上。

2 、半同步复制;

         对于半同步复制,是介于全同步复制和异步复制之间的一种,主库只需要等待至少一个从库节点收到并且Flush Binlog Relay Log 文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全执行并且提交的反馈,这样就节省了很多时间。

         3 、无损复制

         无损复制其实就是对半同步增加了rpl_semi_sync_master_wait_point 参数,来控制半同步模式下主库在返回给会话事务成功之前提交事务的方式。rpl_semi_sync_master_wait_point 该参数有两个值:AFTER_COMMIT AFTER_SYNC

         4 、完全同步的复制;

对于全同步复制,当主库提交事务之后,所有的从库节点必须收到,APPLY 并且提交这些事务,然后主库线程才能继续做后续操作。这里面有一个很明显的缺点就是,主库完成一个事务的时间被拉长,性能降低。

 

mysql5.6 版本以后又进一步的细分成:传统的复制方法和全新的复制方法,全新的复制方式基于GTID ,与传统的复制binglog 格式不同,GTID 模式提供全局的事务号;全新复制模式和与传统的复制模式,从根本上来讲,只是binlog 格式的改变。

MySQL 默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash 掉了,此时主上已经提交的事务可能并没有传到从库上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog ,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。

是介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog Relay Log 文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈,如此,节省了很多时间。

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log 中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP 往返的时间。所以,半同步复制最好在低延时的网络中使用。

 

Loss-less Semi-Synchronous 模式下,master 在调用binlog sync 之后,engine commit 之前等待Slave ACK (需要收到至少一个Slave 节点回复的ACK 后)。这样只有在确认Slave 收到事务events 后,master 事务才会提交,然后把结果返回给客户端。此时此事务才对其他事务可见。在这种模式下解决了after_commit 模式带来的幻读和数据丢失问题,因为主库没有提交事务。但也会有个问题,假设主库在存储引擎提交之前挂了,那么很明显这个事务是不成功的,但由于对应的Binlog 已经做了Sync 操作,从库已经收到了这些Binlog ,并且执行成功,相当于在从库上多了数据,也算是有问题的,但多了数据,问题一般不算严重。这个问题可以这样理解,作为MySQL ,在没办法解决分布式数据一致性问题的情况下,它能保证的是不丢数据,多了数据总比丢数据要好。

无损复制其实就是对semi sync 增加了rpl_semi_sync_master_wait_point 参数,来控制半同步模式下主库在返回给会话事务成功之前提交事务的方式。rpl_semi_sync_master_wait_point 该参数有两个值:AFTER_COMMIT AFTER_SYNC

 

 

半同步复制与无损复制的对比

ACK 的时间点不同:

 

Ø   半同步复制在InnoDB 层的Commit Log 后等待ACK ,主从切换会有数据丢失风险。

Ø   无损复制在MySQL Server 层的Write binlog 后等待ACK ,主从切换会有数据变多风险。

 

主从数据一致性:

Ø   半同步复制意味着在Master 节点上,这个刚刚提交的事物对数据库的修改,对其他事物是可见的。因此,如果在等待Slave ACK 的时候crash 了,那么会对其他事务出现幻读,数据丢失。

Ø   无损复制在write binlog 完成后,就传输binlog ,但还没有去写commit log ,意味着当前这个事物对数据库的修改,其他事物也是不可见的。因此,不会出现幻读,数据丢失风险。

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

当主库提交事务之后,所有的从库节点必须收到、APPLY 并且提交这些事务,然后主库线程才能继续做后续操作。但缺点是,主库完成一个事务的时间会被拉长,性能降低。

 

 

 

MHA keepalived 等组件可以管理MySQL 主从集群,并提供VIP 方式访问,实现故障自动切换。

 

高可用架构

MHA Master High Availability )目前在MySQL 高可用方面是一个相对成熟的解决方案,它由日本DeNA 公司youshimaton (现就职于Facebook 公司)开发,是一套优秀的作为MySQL 高可用性环境下故障切换和主从提升的高可用软件。在MySQL 故障切换过程中,MHA 能做到在10~30 秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在很大程度上保证数据的一致性,以达到真正意义上的高可用。

  MHA 还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中 ( 通过将从库提升为主库) ,大概0.5-2 秒内即可完成。

该软件由两部分组成:MHA Manager (管理节点)和MHA Node (数据节点)。MHA Manager 可以单独部署在一台,独立的机器上管理多个master-slave 集群,也可以部署在一台slave 节点上。MHA Node 运行在每台MySQL 服务器上,MHA Manager 会定时探测集群中的master 节点,当master 出现故障时,它可以自动将最新数据的slave 提升为新的master ,然后将所有其他的slave 重新指向新的master 。整个故障转移过程对应用程序完全透明。

MHA 优点:

Ø   自动故障转移快

Ø   主库崩溃不存在数据一致性问题

Ø   不需要对当前mysql 环境做重大修改

Ø   不需要添加额外的服务器( 仅一台manager 就可管理上百个replication)

Ø   性能优秀,可工作在半同步复制和异步复制,当监控mysql 状态时,仅需要每隔N 秒向master 发送ping ( 默认3 ) ,所以对性能无影响。你可以理解为MHA 的性能和简单的主从复制框架性能一样。

Ø   只要replication 支持的存储引擎,MHA 都支持,不会局限于innodb

 

双主

 

    keepalived vrrp 协议的实现,原生设计目的是为了高可用ipvs 服务,keepalived 能够配置文件中的定义生成ipvs 规则,并能够对各RS 的健康状态进行检测;通过共用的虚拟IP 地址对外提供服务;每个热备组内同一时刻只有一台主服务器提供服务,其他服务器处于冗余状态,若当前在线的服务器宕机,其虚拟IP 地址将会被其他服务器接替(优先级决定接替顺序),实现高可用为后端主机提供服务。

 

PXC Percona Xtradb Cluser

MGC:Mariadb Galera Cluser

Ø   基于Raft 协议的第三方插件Galera Cluster 实现的数据同步技术。

Ø   集群架构,提供多节点写入,允许少数节点crash 且能保证数据不丢失、节点间的数据同步不丢失,节点间数据同步延时较小,但是单位时间的交易量受流控和Galera 插件认证效率影响严重。

 

MGR MySQL Group Replication

Ø   基于Paxos 协议的MySQL 原生插件group replication 实现的同步技术。

Ø   集群架构,既支持单点写入也支持多点写入,允许少数节点crash 且能保证数据不丢失,节点间数据同步延时较小,但是单位时间的交易量受流控影响严重。

 

MGR

PXC MGC

    galera 产品是以galera cluster 方式为mysql 提高高可用集群解决方案的。galera cluster 就是集成了galera 插件的mysql 集群。galera replication codership 提供的mysql 数据同步方案,具有高可用性,方便扩展,并且可以实现多个mysql 节点间的数据同步复制与读写,可保障数据库的服务高可用及数据强一致性。

         galera cluster 的封装有两个,虽然名称不同,但实质都是一样的,使用的都是galera cluster 。一个MySQL 的创始人在自己全新的MariaDB 上实现的MariaDB Galera cluster ;一个是MySQL 服务和工具提供商percona 实现的percona xtradb cluster ,简称PXC

MGR

 

PXC MGC 优点:

1.        多主架构:真正的多点读写集群,在任何时候读写的数据都是最新的;

2.        同步复制:集群不同节点之间的数据同步,没有延迟,在数据库挂掉之后,数据不会丢失;

3.        并发复制:从节点在apply 数据时,支持并行执行,有更好的性能表现

4.        故障切换:因为支持多点写入,所以在出现数据库故障时可以很容易的进行故障切换

5.        热插拔:在服务期间,如果数据库挂了,只要监控程序发现的够快,不可服务时间就会非常少,在节点故障期间,节点本身对集群的影响非常小;

6.        自动节点克隆:在新增节点或停机维护时,增量数据或基础数据不需要人工手动备份提供,galera cluster 会自动拉取在线节点数据,集群最终会变为一致;

7.        对应用透明:集群的维护,对应用程序是透明的,几乎感觉不到;

8.        PXC MGC 缺点:

9.        新加入的节点开销大,需要复制完整的数据。采用SST 传输开销太大。

10.     任何更新事务都需要全局验证通过,才会在每个节点库上执行。集群性能受限于性能最差的节点,也就是经常说的短板效应。

11.     因为需要保证数据的一致性,所以在多节点并发写时,锁冲突问题比较严重。

12.     存在写扩大问题,所有的节点上都会发生些操作。

13.     只支持innodb 存储引擎的表。

14.     没有表级别的锁定,执行DDL 语句操作会把整个集群锁住,而且也 kill 不了(建议使用Osc 操作,即在线DDL

15.     所有的表必须含有主键,不然操作数据时会报错。

 

MGR

         MySQL Group Replication MGR )是MySQL 官方在5.7.17 版本引进的一个数据库高可用与高扩展的解决方案,以插件形式提供。MGR 基于分布式paxos 协议,实现组复制,保证数据一致性。内置故障检测和自动选主功能,只要不是集群中的大多数节点都宕机,就可以继续正常工作。提供单主模式与多主模式,多主模式支持多点写入。MGR 集群的搭建,参考文章MySQL MGR 集群搭建(单主模式& 多主模式)。

 

 

MGR 优点:

 

1.        高一致性:基于分布式paxos 协议实现组复制,保证数据一致性;

2.        高容错性:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制;

3.        高扩展性:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致;

4.        高灵活性:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。

 

MGR 缺点:

 

1.        存储引擎必须为Innodb ,即仅支持InnoDB 表,并且每张表一定要有一个主键,用于做write set 的冲突检测;

2.        每个表必须提供主键;

3.        只支持ipv4 ,网络需求较高;

4.        必须打开GTID 特性,二进制日志格式必须设置为ROW ,用于选主与write set;

5.        COMMIT 可能会导致失败,类似于快照事务隔离级别的失败场景;

6.        目前一个MGR 集群组最多支持9 个节点;

7.        不支持外键于save point 特性,无法做全局间的约束检测与部分部分回滚;

8.        二进制日志binlog 不支持Replication event checksums;

9.        多主模式( 也就是多写模式) 不支持SERIALIZABLE 事务隔离级别;

10.     多主模式不能完全支持级联外键约束;

11.     多主模式不支持在不同节点上对同一个数据库对象并发执行DDL( 在不同节点上对同一行并发进行RW 事务,后发起的事务会失败);

传统的架构模式就是 应用连接数据库直接对数据进行访问,这种架构特点就是简单方便。

当业务快速增长时,此时我们不得不依赖于第二种方式:水平扩展 。直接增加机器,把数据库放到不同服务器上,在应用到数据库之间加一个proxy 进行路由,这样就可以解决上面的问题了。

很多人都会把中间件认为是读写分离,其实读写分离只是中间件可以提供的一种功能,最主要的功能还是在于他可以分库分表。

 

目前市面上中间件种类很多种 先看下各种中间件背景: