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 架构解决高可用性问题可是常用方案,但是存在问题:
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,就会避免出现数据丢失的情况。