「MHA」- 简介

  CREATED BY JENKINSBOT

Overview

https://github.com/yoshinorim/mha4mysql-manager/wiki/Overview

Overview

提供主库故障转移,提升从库为主库
最小化不可用时间(在 10s-30s 间)
保证数据完整性
无需附加服务器
对性能影响小
部署简单,无需调整现有配置

支持在线主库切换,约有 0.5s-2s 的不可用时间(仅阻塞写入)

支持以下功能,并可用在需要 高可用性、数据完整性、近乎不间断主库维护 的部署中。

	**自动主库监控与故障转移:**
	**#** MHA 监控复制环境主库,在主库故障时自动转移,并自动对比 relay log 以同步从库数据,保证数据完整性。
	**#** 故障转移大致为:(1)9-12s 检测主库故障;(2)7-10s 关闭主库防止脑裂(可选);(3)花费少量时间在新主库中应用 relay log。总时间在 10-30s 左右。
	**#** 通过配置文件,可以指定用于用于主库的从库(配置权重)
	**#** 主从数据一致性由 MHA 保证,因此不会出现复制失败问题
	**交互式主库故障转移:**
	**#** 可以将 MHA 配置为手动启动(非自动),交互式故障转移,而无需监视主库。即可以在任何时候进行主库转移。
	**非交互式主库故障转移:**
	**#** 当主库已经使用其他软件监控(比如使用 Pacemaker(Heartbeat) 检测故障)时,可以使用 MHA 进行故障转移。即与其他监控配合实现故障转移。
	**在线切换主库到其他主机:**
	**#** 在某些非故障场景下,我们需要将主库切换到其他主机。对于普通切换方案,需要阻塞旧主库写入,否则无法保证新主库具有最新数据,这会带来服务暂停时间(由于写入阻塞导致)。在同步完成前,新旧节点都不允许进行数据写入,否则会出现数据不一致。
	**#** MHA 提供优雅的主库切换,大概有 0.5-2s 的写入阻塞。对于数据库升级、切换到新主机非常方便。

Difficulties of Master Failover

主库故障切换比较麻烦,没有看起来那么简单。以主从复制为列,当主库故障,需要选择数据最新的从库以提升为主库。但是即使找到最新的主库,如果其他从库没有收到 binlog,在连接到新主库时会丢失事务,导致一致性问题。因此需要将 binlog 同步到各从库,但是难以手动执行。

进行手动故障转移,需要很长时间。并且由于从库可能没有收到 binlog,之后需要手动修复数据一致性问题。虽然不常发生主库崩溃,但是只要发生就很棘手。

MHA 提供手动与自动故障转移:
自动故障转移,使用 masterha_manager 命令,由 Master Monitoring 与 Master Failover 组成。masterha_manager 持续监控主库,如果无法访问主库,它将自动启动非交互式故障转移过程。

手动故障转移,使用 masterha_manager_switch 命令,首先会检查主库是否真的故障,如果断定主库故障,它将选择从库作为新主库(可选择希望的主库),并开始数据恢复与故障转移。内部会执行很多工作,但是我们只需要执行一条命令。

Existing solutions and issues
https://github.com/yoshinorim/mha4mysql-manager/wiki/Other_HA_Solutions.md

Architecture of MHA
https://github.com/yoshinorim/mha4mysql-manager/wiki/Architecture.md

Advantages of MHA
https://github.com/yoshinorim/mha4mysql-manager/wiki/Advantages.md

Use Cases
https://github.com/yoshinorim/mha4mysql-manager/wiki/UseCases.md

其他常见高可用方案及问题

https://github.com/yoshinorim/mha4mysql-manager/wiki/Other_HA_Solutions

Doing everything manually

数据库复制是异步或半同步的。当主库崩溃时,某些从库还没有收到 binlog,此时从库可能处于不同状态。

手动修复不一致问题并不简单,但是如果不修复,复制可能无法开始。另外修复所花费的时间也比较久。

Single master and single slave

在 单主库 + 单从库 中,不会出现“某些从库落后与于最新从库”。当主库崩溃后,故障转移很简单,将流量发送到新主库即可:

M(RW)
 |          --(master crash)-->   M(RW), promoted from S(R)
S(R)

但是单主单从架构会存在问题:
1)流量的压力:所有读库流量都集中在从库上,另外在单从库上的备份、分析、批处理可能会给从库带来性能问题。如果从库崩溃,主库要处理所有流量。
2)可用性问题:如果主库崩溃,则只剩下单个新主库,这会导致单点故障。此时重新添加新从库不但需要时间,从主库备份数据以创建从库会带来读写负载,高峰期可能比较危险。
3)缺乏扩展性:在某些场景下,我们需要使用两个主库,很显然无法使用这种架构。

因此在很多场景中单从架构无法满足。

Master, one candidate master, and multiple slaves

在 单主库 + 候选主库 + 多从库 中,候选主库用于(在主库崩溃时)提升为新主库。在某些场景下,候选主库为只读模式:

      M(RW)-----M2(R)                            M(RW), promoted from M2(R)
       |                                          |
  +----+----+          --(master crash)-->   +-x--+--x-+
 S(R)     S2(R)                             S(?)      S(?)

(From which position should S restart replication?)

作为主库故障转移,该方案也并不总是有效。当主库故障时,从库还没有收到 binlog,依旧需要处理从库的一致性问题。

如果不能接受不一致问题,并且想快速恢复服务,那么只能丢弃从库并将候选主库提升为新主库。但是这会引入在 单主库 + 单从库 中遇到的问题。

该架构也广泛使用,但是存在潜在问题。当主库崩溃之后,从库处于不一致状态,不能直接从新主库开始复制。如果要求数据一致性,那从库就无法使用。

还有 双主分别后缀从库 架构

M(RW)-----M2(R)
 |          |
S(R)      S2(R)

当主库崩溃后,至少还有从库可用,但是很少有人采用这种架构,因为太复杂。此架构使用三层复制(M => M2 => S2),但是管理复杂:如果 M2 崩溃,需要重设 M2 与 S3 节点,并且此架构需要四台服务器。

Pacemaker and DRBD

使用 Pacemaker(Heartbeat) + DRBD + MySQL 架构解决高可用性问题可是常用方案,但是存在问题:

	1)成本较高:该架构属于主备方案,至少需要四台数据库:主库、备用主库(不能处理任何应用流量)、两个从库(其中某个用于报告);
	2)故障时间:当主库故障时,崩溃恢复发生在被动主库上。提升为主库需要时间,尤其是没有使用 InnoDB 插件。即使使用 InnoDB 插件,仍然需要更长时间来接受连接。另外由于被动主库的数据库与文件系统缓存是空的,预热阶段(缓冲填充)仍然需要时间。需要多个从库来处理读取流量。由于缓存是空的,在预热期间,写入性能将显著下降。
	3)性能性能及一致性问题:为了让主被高可用集群生效,在每次提交时,要将事务日志写入磁盘(sync-binlog=1 与 innodb-flush-log-at-trx-commit=1)。但是 sync-binlog=1 会影响写入性能,因为当前 MySQL 序列化 fsync()(如果 sync-binlog=1 将破坏组提交)。另外大家可能没有设置 sync-binlog=1,这就导致事务日志没有写入磁盘,则无法通过 DRDB 同步到被动主库,而主库的从哭却收到事务日志,这就导致被动主库落后于从库,在主库故障后,从库与被动主库数据处于不一致状态。
	4)复杂性:配置 Pacemaker 与 DRDB 复杂,不易使用。尤其是 DRDB 配置,在某些部署中需要重建分区,还需要在 Kernel 与 DRDB 上具有足够经验。如果使用错误命令,将覆盖系统数据。另外在使用 DRDB 时,如果发生 IO 层问题,对于 DBA 来说很难处理(专业方向不同)。

MySQL Cluster

要求使用 NDB 引擎,如果使用 InnoDB 引擎,则无法使用 MySQL Cluster。

Semi-Synchronous Replication

半同步复制是为了降低“binlog 只存在于故障主库”风险,有助于防止数据丢失,但是无法解决一致性问题。半同步复制保证至少有某个从库收到主库在提交时的 binlog 事件,但也不全是。某些主库依旧有可能没有收到 binlog 事件,如果不处理从库数据一致性问题,仍然无法使用。

MHA 可以处理一致性问题,通过结合半同步复制与MHA,可以同时实现“几乎无数据丢失”与“从库一致性”。

Global Transaction ID

GTID 与 MHA 尝试实现的东西相同,但是更多。MHA 只能用于两级复制,而 GTID 则可以用于多层复制环境。即使第二级复制失败,仍然可以恢复第三层从库。

自从 MySQL 5.6 开始,支持 GTID 特性。官方 mysqlfailover 支持使用 GTID 的主库故障转移,MHA 则从 0.56 开始支持。MHA 会自动检测数据库是否开启 GTID,如果开启则使用 GTID 故障转移,否则执行传统故障转移。

架构

https://github.com/yoshinorim/mha4mysql-manager/wiki/Architecture

当主库崩溃时,MHA 按照如下步骤恢复剩下的从库:

详细参考 Automated master failover,尤其是 no.13 与 no.34

在从库的 relaylog 中,主库的 binlog 位置保存在 end_log_pos 部分,通过比较该值,可以确定没有发送的事件。在修复一致性问题时,MHA 内部使用该机制,但是内部还进行优化与加强(比如快速生成不同的 relaylog;使基于行的数据恢复)。

MHA Components – MHA Manager and MHA Node


MHA Manager 包含管理程序,比如:监控 MySQL 主库;控制主库故障转移。

MHA Node 包含故障转移脚本,比如:relaylog/binlog 解析;识别 relaylog 位置,从该位置开始应用 relaylog 到其他从库;应用事件给目标从库;

当 MHA Manager 进行故障转移时,MHA Manager 通过 SSH 连接到 MHA Node 执行管理命令。

Custom Extensions

还有些可以扩展的地方,比如:可以执行自定义脚本更新主节点的网络地址(更新管理主节点网络地址的全局编录数据库,更新虚拟地址),该操作与用户环境相关,所有 MHA 不负责。

目前有以下扩展点(MHA Manager 包含简单脚本):
1)secondary_check_script:从多网络路由检查主节点的可用性;
2)master_ip_failover_script:用于更新在应用程序中使用的网络地址;
3)shutdown_script:强制关闭主库;
4)report_script:发送报告;
5)init_conf_load_script:加载初始化配置参数;
6)master_ip_online_change_script:用于更新主节点网络地址(不用于故障切换,而用于在线主节点切换)

优势

https://github.com/yoshinorim/mha4mysql-manager/wiki/Advantages

Master failover and slave promotion can be done very quickly

如果从库没有严重的复制延迟,可以快速完成故障转移(大约 10-30s 左右)。在恢复主库后,并行恢复从库,即使有很多从库,它也不会影响主库恢复时间,并且可以快速恢复从库。

DeNA 的 MHA 环境有 150+ 主从环境,可在 4s 内恢复,以往主备集群很难达到这个速度。

Master crash does not result in data inconsistency

当主节点崩溃时,MHA 将自动在从库应用 relaylog 以处理数据不一致问题。

如果配合半同步复制(Semi-Synchronous Replication)可以保证无数据丢失。

No need to modify current MySQL settings

使用 MHA 需要 MySQL 5.0+ 版本;
无需修改当前数据库部署设置;
可以当前两级的单主多从集群协作;
可以异步复制及半同步复制协作;
对 MHA 的调整(升级降级停止启动)不会影响到数据库;

No need to increase lots of servers

MHA Node 与 MySQL 同时运行于相同主机;MHA Manager 用于监控,但是可以监控多台主机(100+)

甚至 MHA Manager 与 MHA Node 可以部署在相同主机上,如此一来完全无需增加主机。

No performance penalty

MHA 只向主库发送 ping 包,默认三秒每次,不会带来过大的数据库压力,自然不会影响数据库复制;

Works with any storage engine

MHA 可与任何数据库引擎协作,不限 InnoDB,只要支持数据库复制即可。

Typical Use Cases

https://github.com/yoshinorim/mha4mysql-manager/wiki/UseCases

在哪里部署 MHA Manager?

专用的 MHA Manager 服务器:由于 MHA Manager 占用资源极少,可以使用单个 MHA Manager 管理许多主从服务器,甚至可能管理 100 多对。

运行 MHA Manager 于从库上:如果不想增加主机,可以将数据库运行在从库上。注意即使在同一主机,MHA 仍然通过 SSH 连接主机。

复制配置

Single master, multiple slaves,这是最常见的复制架构:

        M(RW)                                       M(RW), promoted from S1
         |                                           |
  +------+------+        --(master crash)-->   +-----+------+
S1(R)  S2(R)  S3(R)                          S2(R)        S3(R)

Single master, multiple slaves (one on remote datacenter),该架构中有台从库运行在远程数据中心,在故障时,我们不希望他被提升为主库,可以在 MHA 配置中指定 no_master = 1 来实现:

        M(RW)                                        M(RW), promoted from S1
         |                                            |
  +------+------+        --(master crash)-->   +------+------+
S1(R)  S2(R)  Sr(R,no_master=1)              S2(R)         Sr(R,no_master=1)

Single master, multiple slaves, one candidate master,在故障时,如果希望提升特定主机,可以在 MHA 配置中设置 candidate_master = 1 可在故障时,提升该主机为新的主库:

        M(RW)-----S0(R,candidate_master=1)           M(RW), promoted from S0
         |                                            |
  +------+------+        --(master crash)-->   +------+------+
S1(R)         S2(R)                          S1(R)         S2(R)

Multiple masters, multiple slaves,在该架构中有台候选主库,在 MHA 配置中设置 candidate_master = 1 即可,在故障时提升该候选主库为新的主库:

       M(RW)<--->M2(R,candidate_master=1)           M(RW), promoted from M2
        |                                            |
 +------+------+        --(master crash)-->   +------+------+
S(R)         S2(R)                          S1(R)      S2(R)

Three tier replication,三级复制。在配置文件中,MHA 只需管理 M,S1,S2,Sr 节点。在故障时,找要 Sr 存活,就不会影响到 Sr2 节点。但是如果 Sr 崩溃,那么 Sr2 则无法继续进行复制。另外 MHA 不能用于恢复 Sr2 节点。在实践中,Sr2 不要过于重要,否则会大面积影响业务。另外如果使用 GTID 复制,那恢复起来也会比较容易。

        M(RW)                                        M(RW), promoted from S1
         |                                            |
  +------+------+        --(master crash)-->   +------+------+
S1(R)  S2(R)  Sr(R)                          S2(R)         Sr(R)
			   |                                             |
			   +                                             +
			  Sr2                                           Sr2

Three tier replication, multi-master,在该架构中,host5 为三级从库,MHA 不管理 host5 节点(即不会执行 CHNAGE MASTER 语句,因为没有意义),而 host3 与 host4 将会被同步切换到新主库:

       M1(host1,RW) <-----------------> M2(host2,read-only)
         |                                |
  +------+------+                         +
S1(host3,R)   S2(host4,R)               S3(host5,R)

==========>>>>>>>>> After failover

             M2(host2,RW)
               |
+--------------+--------------+
S1(host3,R) S2(host4,R) S3(host5,R)

配置文件大概是这个样子:

[server default]
multi_tier_slave=1

[server1]
hostname=host1
candidate_master=1

[server2]
hostname=host2
candidate_master=1

[server3]
hostname=host3

[server4]
hostname=host4

[server5]
hostname=host5

Managing Master IP address

在常见高可用方案中,采用虚拟网络地址(VIP),新节点将接管该地址。另外一种方案是,采用全局编录数据库(可以理解为配置中心)。在故障时,更新应用程序所使用的数据库配置信息。

MHA 并不关心使用那种方案,在故障时,它会执行 master_ip_failover_script 参数指定的脚本,由用户来实现具体的工作。

或者使用其他高可用方案,自动处理网络地址。

Using together with Semi-Synchronous Replication

如果主库磁盘崩溃或者无法远程,此时 MHA 将无法获取主库的 binlog,这会导致数据丢失。

如果启用半同步复制,只要有某个从库收到 binlog,就会避免出现数据丢失的情况。