探讨 `MHA`(`Master High Availability`)的`高可用`脚本与`故障`切换`策略`。

MHA 高可用脚本与故障切换策略:深度解析

大家好!今天我们来深入探讨 MHA (Master High Availability) 的高可用脚本与故障切换策略。MHA 是一套优秀的 MySQL 高可用解决方案,它能在主库发生故障时,自动将其中一个 Slave 提升为新的 Master,从而保障数据库服务的持续可用性。

今天的内容将涵盖 MHA 的核心组件、工作原理,以及如何编写和配置自定义脚本来实现更精细化的故障切换控制。

1. MHA 的核心组件与工作原理

MHA 主要由两个核心组件构成:

  • MHA Manager (管理节点): 负责监控 MySQL 集群的状态,检测 Master 节点是否发生故障,并在故障发生时执行故障切换。

  • MHA Node (数据节点): 部署在 MySQL 服务器上,负责执行 Manager 发出的指令,例如启动、停止 MySQL 服务,执行数据恢复等操作。

工作原理:

  1. 监控: MHA Manager 定期通过 SSH 连接到 MySQL 服务器,执行 SHOW SLAVE STATUSSHOW MASTER STATUS 等命令,检查 Master 是否正常运行,以及 Slave 的复制状态。
  2. 故障检测: 如果 Manager 在预定时间内无法连接到 Master,或者检测到 Master 的复制状态异常,则判定 Master 发生故障。
  3. 故障切换: Manager 会根据预先设定的策略,选择一个合适的 Slave 作为新的 Master。
  4. 数据恢复: Manager 会将新的 Master 的二进制日志位置同步到其他 Slave,确保所有 Slave 都能从新的 Master 继续复制数据。
  5. 客户端重定向: Manager 会更新客户端的连接配置,将客户端重定向到新的 Master。

2. MHA 的故障切换策略

MHA 提供了多种故障切换策略,可以根据不同的业务需求进行选择。常见的策略包括:

  • 最先进策略 (Most Up-to-Date Slave): 选择复制延迟最小的 Slave 作为新的 Master,保证数据一致性最高。

  • 指定优先级策略 (Preferred Slave): 可以为 Slave 设置优先级,MHA 会优先选择优先级最高的 Slave 作为新的 Master。

  • 手动切换策略 (Manual Failover): 手动指定新的 Master,适用于需要人工干预的场景。

MHA 默认使用最先进策略,但在实际应用中,可以通过配置 preferred_master_candidateno_master_candidate 等参数,来调整 Slave 的选择优先级。

3. 自定义 MHA 脚本:扩展故障切换能力

MHA 允许用户自定义脚本,在故障切换的不同阶段执行特定的操作。这为我们提供了极大的灵活性,可以根据业务需求定制故障切换流程。

MHA 支持以下几种类型的自定义脚本:

  • master_ip_online_change: 在新的 Master 上线时执行。
  • master_ip_offline_change: 在旧的 Master 下线时执行。
  • secondary_check_script: 在故障检测阶段执行,用于更精确地判断 Master 是否发生故障。
  • pre_switchover_script: 在故障切换开始前执行。
  • post_switchover_script: 在故障切换完成后执行。
  • pre_online_change_script: 在新的 Master 上线前执行。
  • post_online_change_script: 在新的 Master 上线后执行。
  • pre_offline_change_script: 在旧的 Master 下线前执行。
  • post_offline_change_script: 在旧的 Master 下线后执行。

3.1 脚本参数

MHA 在执行自定义脚本时,会传递一些参数,这些参数包含了集群的信息、新旧 Master 的信息等。常见的参数包括:

  • --manager: MHA Manager 的主机名或 IP 地址。
  • --appname: 应用名称。
  • --new_master_host: 新的 Master 的主机名。
  • --new_master_ip: 新的 Master 的 IP 地址。
  • --new_master_port: 新的 Master 的端口号。
  • --orig_master_host: 旧的 Master 的主机名。
  • --orig_master_ip: 旧的 Master 的 IP 地址。
  • --orig_master_port: 旧的 Master 的端口号。
  • --candidate_master_host: 候选 Master 的主机名。
  • --candidate_master_ip: 候选 Master 的 IP 地址。
  • --candidate_master_port: 候选 Master 的端口号。

3.2 脚本示例

下面我们来看几个自定义脚本的示例,演示如何利用这些脚本来扩展 MHA 的故障切换能力。

示例 1: master_ip_online_change 脚本:更新 DNS 记录

这个脚本的作用是在新的 Master 上线时,自动更新 DNS 记录,将域名指向新的 Master 的 IP 地址。

#!/bin/bash

# 获取参数
NEW_MASTER_IP=$1
APP_NAME=$2

# 更新 DNS 记录
# 这里需要根据你的 DNS 服务商提供的 API 进行修改
# 假设使用 Cloudflare API
ZONE_ID="your_zone_id"
RECORD_ID="your_record_id"
API_TOKEN="your_api_token"

curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" 
     -H "Authorization: Bearer ${API_TOKEN}" 
     -H "Content-Type: application/json" 
     --data "{"type":"A","name":"mysql.example.com","content":"${NEW_MASTER_IP}","ttl":120,"proxied":false}"

if [ $? -eq 0 ]; then
  echo "DNS record updated successfully to ${NEW_MASTER_IP}"
else
  echo "Failed to update DNS record"
  exit 1
fi

exit 0

配置方法:

在 MHA 的配置文件中,添加以下配置:

master_ip_online_change=/path/to/master_ip_online_change.sh

示例 2: secondary_check_script 脚本:自定义健康检查

这个脚本的作用是在故障检测阶段,执行自定义的健康检查,例如检查 MySQL 的连接数、QPS 等指标,更精确地判断 Master 是否发生故障。

#!/bin/bash

# 获取参数
MASTER_HOST=$1
MASTER_PORT=$2

# 执行健康检查
# 这里需要根据你的业务需求进行修改
MYSQL_CONN=$(mysql -h ${MASTER_HOST} -P ${MASTER_PORT} -u root -e "show status like 'Threads_connected';" | awk '/Threads_connected/ {print $2}')
MYSQL_QPS=$(mysql -h ${MASTER_HOST} -P ${MASTER_PORT} -u root -e "show status like 'Questions';" | awk '/Questions/ {print $2}')

if [ -z "${MYSQL_CONN}" ] || [ -z "${MYSQL_QPS}" ]; then
  echo "Failed to get MySQL status"
  exit 1
fi

if [ ${MYSQL_CONN} -gt 1000 ] || [ ${MYSQL_QPS} -gt 10000 ]; then
  echo "MySQL is overloaded"
  exit 1
fi

# 如果健康检查通过,则返回 0
exit 0

配置方法:

在 MHA 的配置文件中,添加以下配置:

secondary_check_script=/path/to/secondary_check_script.sh

示例 3: pre_switchover_script 脚本:锁定应用程序

这个脚本的作用是在故障切换开始前,锁定应用程序,防止在切换过程中产生新的数据写入。

#!/bin/bash

# 获取参数
APP_NAME=$1

# 锁定应用程序
# 这里需要根据你的应用程序的特点进行修改
# 假设使用 Nginx 作为反向代理,可以通过修改 Nginx 配置来实现锁定
NGINX_CONFIG="/etc/nginx/nginx.conf"

# 备份 Nginx 配置文件
cp ${NGINX_CONFIG} ${NGINX_CONFIG}.bak

# 修改 Nginx 配置文件,返回 503 错误
sed -i "s/proxy_pass http://backend;/return 503;/" ${NGINX_CONFIG}

# 重启 Nginx
systemctl reload nginx

if [ $? -eq 0 ]; then
  echo "Application locked successfully"
else
  echo "Failed to lock application"
  exit 1
fi

exit 0

配置方法:

在 MHA 的配置文件中,添加以下配置:

pre_switchover_script=/path/to/pre_switchover_script.sh

示例 4: post_switchover_script 脚本:解锁应用程序

这个脚本的作用是在故障切换完成后,解锁应用程序,允许新的数据写入。

#!/bin/bash

# 获取参数
APP_NAME=$1

# 解锁应用程序
# 这里需要根据你的应用程序的特点进行修改
# 假设使用 Nginx 作为反向代理,可以通过恢复 Nginx 配置来实现解锁
NGINX_CONFIG="/etc/nginx/nginx.conf"

# 恢复 Nginx 配置文件
mv ${NGINX_CONFIG}.bak ${NGINX_CONFIG}

# 重启 Nginx
systemctl reload nginx

if [ $? -eq 0 ]; then
  echo "Application unlocked successfully"
else
  echo "Failed to unlock application"
  exit 1
fi

exit 0

配置方法:

在 MHA 的配置文件中,添加以下配置:

post_switchover_script=/path/to/post_switchover_script.sh

4. MHA 配置文件详解

MHA 的配置文件主要有两个:

  • manager.cnf: MHA Manager 的配置文件,用于配置集群信息、监控策略、故障切换策略等。
  • node.cnf: MHA Node 的配置文件,用于配置 MySQL 服务器的信息、SSH 连接信息等。

4.1 manager.cnf 常用配置项

配置项 说明
appname 应用名称,用于区分不同的 MHA 集群。
user 连接 MySQL 服务器的用户名。
password 连接 MySQL 服务器的密码。
ssh_user SSH 连接 MySQL 服务器的用户名。
ssh_key SSH 连接 MySQL 服务器的私钥文件路径。
master_binlog_dir Master 节点的二进制日志目录。
candidate_master 指定候选 Master 的主机名或 IP 地址。
preferred_master_candidate 优先选择的 Master 候选节点。
no_master_candidate 不允许作为 Master 候选节点的服务器。
master_ip_online_change 在新的 Master 上线时执行的脚本路径。
master_ip_offline_change 在旧的 Master 下线时执行的脚本路径。
secondary_check_script 在故障检测阶段执行的脚本路径。
ping_type Master 节点健康检查的方式,可选值包括 pingmysql
ping_interval Master 节点健康检查的间隔时间,单位为秒。
max_failover_attempts 最大故障切换尝试次数。
report_script 报警脚本路径,用于发送故障通知。
shutdown_script 关闭旧 Master 的脚本路径。
remove_master_relay_log 是否在故障切换后删除旧 Master 上的 relay log。

4.2 node.cnf 常用配置项

配置项 说明
user 连接 MySQL 服务器的用户名。
password 连接 MySQL 服务器的密码。
ssh_user SSH 连接 MySQL 服务器的用户名。
ssh_key SSH 连接 MySQL 服务器的私钥文件路径。
port MySQL 服务器的端口号。

5. 故障切换测试与验证

配置完 MHA 后,需要进行故障切换测试,验证 MHA 是否能够正常工作。

测试步骤:

  1. 模拟 Master 节点故障,例如停止 MySQL 服务。
  2. 观察 MHA Manager 是否能够检测到故障。
  3. 观察 MHA Manager 是否能够自动执行故障切换。
  4. 验证新的 Master 是否能够正常提供服务。
  5. 验证 Slave 是否能够从新的 Master 继续复制数据。
  6. 验证客户端是否能够自动连接到新的 Master。
  7. 验证自定义脚本是否能够正常执行。

6. MHA 的局限性与替代方案

MHA 是一种优秀的 MySQL 高可用解决方案,但它也有一些局限性:

  • 不支持自动创建 Slave: MHA 只能管理已经存在的 Slave,无法自动创建新的 Slave。
  • 依赖 SSH 连接: MHA 需要通过 SSH 连接到 MySQL 服务器,这可能会带来安全风险。
  • 不支持复杂的拓扑结构: MHA 对拓扑结构有一定的要求,不支持复杂的拓扑结构。

针对 MHA 的局限性,可以考虑使用其他的 MySQL 高可用解决方案,例如:

  • MySQL Group Replication: MySQL 官方提供的高可用方案,支持多主复制,数据一致性更高。
  • Galera Cluster: 基于 Galera 技术的 MySQL 集群,支持多主复制,数据一致性更高。
  • Orchestrator: 另一个开源的 MySQL 高可用解决方案,功能更强大,支持更复杂的拓扑结构。

7. 总结关键要点

MHA 是一种强大的 MySQL 高可用工具,通过自定义脚本,可以灵活地扩展其功能。理解 MHA 的工作原理和配置选项,能够帮助我们构建稳定可靠的 MySQL 集群。在选择高可用方案时,需要根据业务需求和实际情况进行综合考虑。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注