构建高可用的 MySQL
如何高可用
说起高可用,不同的中间件、不用的应用、它们有自己不同的方案。但是总结起来无非大概就如下三点:
避免单点
数据冗余
故障自动转移
"避免单点"这个词很好理解。假设你就一台服务器,不管怎么做你都是无法做到高可用的,毕竟服务器就你一台,你要是挂了的话你还怎么传宗接代?还有就是单点对于服务器的压力也比较大,如果有多台机器,把请求均摊到各个机器,并且在其中一台机器挂了的时候,还有其它机器可以对外服务。
''数据冗余''怎么理解呢?冗余也就是多余的意思,换句话说就是我需要的东西你得给我备份好一份,对于 mysql 来说就是至少得有一个主库和一个从库,这样主库故障的时候,从库也有我需要的数据。并且从库也可以替代异常的主库成为主库
''故障自动转移''怎么理解呢?以 mysql 来说就是比如我从库原本只是用来备份数据和提供读服务,但是此时主库挂了,这个时候最好能自动将从库升级成主库吧,要是叫我手动切换那肯定很麻烦啊。我要是在睡觉呢?要是没有及时发现故障呢?所以故障自动转移的自动还是很重要的
上面讲的都比较基础,真实实现起来还有很多复杂的东西需要考虑。比如备份数据如何保持一致、如何选主等问题。下面来讲一下常见的一个 mysql 的高可用方案。
避免单点与数据冗余
mysql 避免单点我想大家都已经很熟了,最简单的就是两台服务器,一主一从呗,这不就简简单单的避免单点了。那数据冗余怎么做呢?传统的 MySQL 复制提供了一种简单的主从复制方法。有一个 master 和一个或多个 slave。master 执行事务,提交它们,然后异步发送到 slave 节点以重新执行默认情况下所有服务器都有数据的完整副本。mysql 的主从复制技术提供了两种复制方案,一个是异步复制、一个是半同步复制。
异步复制
(图片来自 MySQL 官网)
流程可以概述如下:
master 更新事件被写到 binlog
master 创建一个 binlog dump thread,把 binlog 的内容发送到从库
slave 创建一个 I/O 线程,读取主库传过来的 binlog 内容并写入到中继日志(relay log)
slave 的 SQL 线程,从 relay log 里面读取内容,将更新内容写入到自己的 db 的
这种模式 master 不需要等待 slave 同步到数据就能进行提交事务,牺牲了数据的一致性,不能保证主从的数据一致性
半同步复制
(图片来自 MySQL 官网)
如上图所示,在一主两从架构下在 master 执行后写入 binlog、然后 master 把 binlog 日志推送给 salve1 和 slave2 ,半同步复制情况下 master 需要等待其中任意一个 slave 更新数据到 relay log 成功并且给 master 回复 ack,master 才提交事务,这样至少有一个 slave 同步数据了,这样就能保证数据一致性了。但是半同步复制还有一个问题就是数据延迟问题,因为半同步数据复制并不要求那些事件完全地执行,只要写到 relay log 就可以了,如果从库压力太大,可能延迟会比较严重。所以在 MySQL5.7 的版本又引入一种新的复制技术:组复制
组复制(MySQL Group Replication)
MGR(MySQL Group Replication)是 MySQL 自带的一个插件,可以灵活部署。建立在 Paxos 分布式算法的实现之上,以提供服务器之间的分布式协调。
(图片来自 MySQL 官网,缺少一些潜在的共识算法和 Paxos 相关信息。)
以上图为例,复制组是由多个 server 构成,它有两种模式,由 group_replication_single_primary_mode 来控制,当 group_replication_single_primary_mode = ON 时表示单主模式(也是默认模式),当 group_replication_single_primary_mode = OFF 时表示多主模式,以单主模式为例,当一个事务发起提交,它会通过原子广播协议将事务伴随着 Binlog 广播到其他 slave 节点上、然后会为该事务建立一个全局的顺序。所以 server 成员以相同的顺序接收同一组事务以确保组内一致。在获得集群大多数节点同意之后,它会进行一个提交。如果通过冲突认证检测,那么该事务最终会在集群当中提交。
它具有如下特点:
一致性高
基于 Paxos 算法,提供了强一直性保证,可以确实在大部分节点数据得到同步
容错性高
因为建立在 Paxos 分布式算法的实现之上,所以它需要大多数服务器处于活动状态才能达到法定人数并做出决定。下表为官方提供的不同的组成员的容错性:
Group Size:组成员大小,最大为 9
Majority:存活的组员最小值
Instant Failures Tolerated:允许挂掉的机器数量
这意味着要容忍一个故障,该组中必须有三台以上服务器。因此,如果一台服务器出现故障,仍有 n/2 + 1 台服务器组成多数并允许系统继续自动做出决策并继续正常的执行下去。
扩展性高
组成员自动管理。节点的新增和移除都是自动的(具备故障检测),新节点加入后,会自动从其他节点上同步信息和状态。
以上内容只是简单简绍了组复制技术的原理,具体内容可以参考官网或者相关文章。讲到这里我们也只是解决了高可用的两个问题,也就是避免单点和数据冗余,还有一个故障自动转移没有处理,组复制技术并不处理这个问题,那如何解决呢?
故障自动转移
mysql 官网在讲组复制技术的时候,提到了可以使用 MySQL Router 8.0 来解决这个问题,但我下面讲的是另外一个介由 mariadb 公司出品的中间件 Maxscale,官方文档为https://mariadb.com/kb/en/maxscale/,它可以实现读写分离和读负载均衡以及故障自动转移。具体实现可以参考官网和网上相关资料。
最终高可用方案图
最终形成的高可用架构如上,client 请求先经过 maxscale 然后由 maxscale 转发到指定的 member1 进行处理,由 maxscale 保证故障自动转移、负载均衡等,由 mysql 的组复制保证数据的一致性。
评论