云原生数据库高可用:配置 MySQL 自动故障转移(MGR)与 K8s 服务发现

在云原生环境中,实现数据库高可用至关重要。MySQL Group Replication (MGR) 提供自动故障转移能力,确保数据库在节点故障时无缝切换;而 Kubernetes (K8s) 服务发现则通过 DNS 或 Service 自动路由流量到健康实例。本指南将逐步指导您完成配置,确保高可用性和可靠性。以下是结构化步骤:

1. 理解核心组件
  • MySQL Group Replication (MGR):基于 Paxos 协议的分布式集群,实现自动故障转移。当节点故障时,集群通过多数投票机制(公式:$ \text{quorum} = \left\lfloor \frac{n}{2} \right\rfloor + 1 $,其中 $ n $ 是节点总数)选举新主节点。
  • K8s 服务发现:使用 Kubernetes Service(如 Headless Service)和 DNS 自动发现数据库实例。服务发现公式可表示为 $ \text{请求路由} = \frac{\text{总流量}}{\text{健康节点数}} $,确保负载均衡。
2. 配置 MySQL MGR 集群

在 Kubernetes 环境中,推荐使用 StatefulSet 部署 MySQL 实例,以保持持久化存储和稳定网络标识。以下是关键步骤:

  • 步骤 1: 初始化 MySQL 配置

    • 在每个 MySQL Pod 的配置文件中,启用 MGR 插件。示例配置(my.cnf):
      [mysqld]
      plugin-load-add=group_replication.so
      group_replication_group_name="my-mgr-cluster"
      group_replication_start_on_boot=ON
      group_replication_bootstrap_group=OFF
      server-id=1  # 每个节点唯一 ID
      

    • 公式:集群健康检查依赖于节点间心跳,超时阈值 $ t $ 通常设置为 $ t \leq 5 \text{秒} $ 以避免误判。
  • 步骤 2: 创建 MGR 集群

    • 在第一个节点上执行 SQL 命令初始化集群:
      SET GLOBAL group_replication_bootstrap_group=ON;
      START GROUP_REPLICATION;
      SET GLOBAL group_replication_bootstrap_group=OFF;
      

    • 添加其他节点:
      CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';
      START GROUP_REPLICATION;
      

    • 验证集群状态:SELECT * FROM performance_schema.replication_group_members;,输出应显示所有节点为 ONLINE
3. 部署到 Kubernetes 并设置服务发现

使用 Kubernetes StatefulSet 和 Service 管理 MySQL 集群,确保自动故障转移和流量路由。

  • 步骤 1: 定义 StatefulSet

    • 创建 YAML 文件(mysql-statefulset.yaml),使用 Init Container 配置 MGR:
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: mysql-mgr
      spec:
        serviceName: mysql-headless
        replicas: 3  # 推荐至少 3 节点以实现高可用
        selector:
          matchLabels:
            app: mysql
        template:
          metadata:
            labels:
              app: mysql
          spec:
            initContainers:
            - name: init-mysql
              image: mysql:8.0
              command: ['sh', '-c', 'echo "配置 MGR 初始化脚本..."']
            containers:
            - name: mysql
              image: mysql:8.0
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: "rootpass"
              ports:
              - containerPort: 3306
              volumeMounts:
              - name: mysql-data
                mountPath: /var/lib/mysql
        volumeClaimTemplates:
        - metadata:
            name: mysql-data
          spec:
            accessModes: [ "ReadWriteOnce" ]
            resources:
              requests:
                storage: 10Gi
      

    • 公式:StatefulSet 确保 Pod 顺序启动,节点标识稳定,满足 MGR 的 $ \text{quorum} $ 要求。
  • 步骤 2: 配置 Headless Service 用于服务发现

    • 创建 Service YAML(mysql-service.yaml):
      apiVersion: v1
      kind: Service
      metadata:
        name: mysql-headless
      spec:
        clusterIP: None  # Headless Service
        ports:
        - port: 3306
        selector:
          app: mysql
      

    • 服务发现机制:K8s DNS 自动解析为 Pod IP(如 mysql-mgr-0.mysql-headless.default.svc.cluster.local),应用通过此域名连接数据库,实现故障转移后自动重定向。
4. 测试故障转移和服务发现
  • 故障转移测试
    • 模拟节点故障:kubectl delete pod mysql-mgr-0
    • 监控 MGR 状态:在剩余节点上运行 SELECT * FROM performance_schema.replication_group_members;,验证新主节点选举(通常在 $ \leq 10 \text{秒} $ 内完成)。
    • 服务发现验证:应用连接 mysql-headless 域名,流量自动路由到健康节点。
  • 公式验证:故障转移时间 $ T $ 应满足 $ T \leq \text{心跳超时} + \text{选举延迟} $,优化后可达 $ T < 5 \text{秒} $。
5. 最佳实践与注意事项
  • 安全性:使用 Kubernetes Secrets 存储数据库密码,避免硬编码。
  • 监控:集成 Prometheus 和 Grafana 监控 MGR 指标,如节点状态和复制延迟。
  • 备份:定期快照持久卷,并测试恢复流程。
  • 扩展性:添加节点时,确保新节点满足 $ n \mod 2 \neq 0 $ 以维持奇数节点数,防止脑裂。
  • 推荐工具:使用 MySQL Operator(如 Oracle MySQL Operator)简化部署。
总结

通过结合 MySQL MGR 的自动故障转移和 Kubernetes 服务发现,您可以在云原生环境中实现高可用数据库。MGR 处理节点故障,而 K8s 服务确保应用无缝连接。部署后,测试故障转移场景以验证可靠性。此方案适用于生产环境,能显著提升数据库可用性(目标可达 99.99%)。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐