一、InnoDB Cluster 概述
1. 核心定义
InnoDB Cluster 是 MySQL 官方实现的高可用 + 读写分离的架构方案,包含以下核心组件:
- MySQL Router:业务流量入口,支持对 MGR 的主从角色判断,提供读写分离
- 组复制(Group Replication:实现数据同步和角色选举
- MySQL Shell:集群管理工具,用于创建和管理集群
2. 架构特点
- 三个 MySQL 数据库实例构成高可用集群
- 一个实例为读写能力的主要成员(PRIMARY)
- 其他两个实例为只读能力的次要成员(SECONDARY)
- 通过组复制将数据从主节点复制到从节点
- MySQL Router 将客户端连接到集群的主节点
重要提示:InnoDB Cluster 只有与组复制和 MySQL Shell 共同使用,才能称为 InnoDB Cluster。
二、InnoDB Cluster 架构优势
1. 与传统主从复制的区别
| 特性 | 传统主从复制 | InnoDB Cluster |
|---|---|---|
| 高可用 | 需手动故障转移 | 自动故障转移 |
| 读写分离 | 需额外中间件 | MySQL Router 内置支持 |
| 集群管理 | 无统一管理工具 | MySQL Shell 统一管理 |
| 数据一致性 | 可能存在延迟 | 强一致性保障 |
| 节点状态监控 | 需手动检查 | 集群状态可视化 |
2. 核心优势
- 自动故障转移:节点故障时自动选举新主节点
- 读写分离:MySQL Router 自动将读请求分发到从节点
- 简化管理:通过 MySQL Shell 统一管理集群
- 数据强一致性:组复制保证数据同步
- 高可用保障:3 节点集群允许 1 节点宕机,服务仍可用
三、集群搭建实战
1. 环境准备
| 主机名 | 角色 | server_id | 宿主机 IP | 容器 IP | DB Port |
|---|---|---|---|---|---|
| mgr-node1 | PRIMARY | 1 | 192.168.65.223 | 172.19.0.10 | 3321 → 3306 |
| mgr-node2 | SECONDARY | 2 | 192.168.65.223 | 172.19.0.11 | 3322 → 3306 |
| mgr-node3 | SECONDARY | 3 | 192.168.65.223 | 172.19.0.12 | 3323 → 3306 |
2. 关键配置
所有实例必须配置:
[mysqld]
server_id=1 # 三个实例需不同
gtid_mode=ON
enforce_gtid_consistency=ON
log-bin=mysql-bin
binlog_transaction_dependency_tracking=WRITESET
replica_preserve_commit_order=ON
replica_parallel_type=LOGICAL_CLOCK
transaction_write_set_extraction=XXHASH64
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
注意:从 8.0.23 开始,集群中的实例要启用并行复制。
3. Docker 部署步骤
-
创建网络 :
bashdocker network create --driver bridge --subnet 172.19.0.0/24 --gateway 172.19.0.1 mgr-network -
创建目录 :
bashmkdir -p /mysql/mgr/node1/{data,conf,log} mkdir -p /mysql/mgr/node2/{data,conf,log} mkdir -p /mysql/mgr/node3/{data,conf,log} -
启动 MySQL 容器 :
bashdocker run -d \\ --name mgr-node1 \\ --privileged=true \\ --restart=always \\ --ip 172.19.0.10 \\ --hostname mgr-node1 \\ --add-host mgr-node2:172.19.0.11 \\ --add-host mgr-node3:172.19.0.12 \\ --network mgr-network \\ -p 3321:3306 \\ -v /mysql/mgr/node1/data:/var/lib/mysql \\ -v /mysql/mgr/node1/conf:/etc/mysql/conf.d \\ -v /mysql/mgr/node1/log:/logs \\ -e MYSQL_ROOT_PASSWORD=123456 \\ -e TZ=Asia/Shanghai mysql:8.0.27 \\ --lower_case_table_names=1 -
配置远程访问 :
sqlALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;
4. 安装 MySQL Router 和 MySQL Shell
安装 MySQL Router:
bash
wget <https://downloads.mysql.com/archives/router/mysql-router-community-8.0.27-1.el7.x86_64.rpm>
rpm -ivh mysql-router-community-8.0.27-1.el7.x86_64.rpm
安装 MySQL Shell:
bash
wget <https://downloads.mysql.com/archives/shell/mysql-shell-8.0.27-1.el7.x86_64.rpm>
rpm -ivh mysql-shell-8.0.27-1.el7.x86_64.rpm
四、集群初始化与管理
1. 集群初始化
检查实例配置:
jsx
dba.checkInstanceConfiguration('root@mgr-node1:3306');
dba.checkInstanceConfiguration('root@mgr-node2:3306');
dba.checkInstanceConfiguration('root@mgr-node3:3306');
配置实例:
jsx
dba.configureInstance('root@mgr-node1:3306');
dba.configureInstance('root@mgr-node2:3306');
dba.configureInstance('root@mgr-node3:3306');
创建集群:
jsx
var cluster = dba.createCluster('myCluster');
cluster.status();
添加副本节点:
jsx
cluster.addInstance('root@mgr-node2:3306');
cluster.addInstance('root@mgr-node3:3306');
2. 集群常用命令
| 命令 | 说明 |
|---|---|
cluster.status() |
查看集群状态 |
cluster.checkInstanceState("root@hostname:3306") |
检查节点状态 |
cluster.addInstance("root@hostname:3306") |
添加节点 |
cluster.removeInstance("root@hostname:3306") |
删除节点 |
cluster.rejoinInstance("root@hostname:3306") |
重新加入集群 |
cluster.dissolve({force:true}) |
解散集群 |
cluster.describe() |
查看集群描述 |
3. 集群节点状态
| 状态 | 说明 |
|---|---|
| ONLINE | 节点状态正常 |
| OFFLINE | 实例在运行,但未加入集群 |
| RECOVERING | 实例已加入集群,正在同步数据 |
| ERROR | 同步数据发生异常 |
| UNREACHABLE | 与其他节点通讯中断 |
| MISSING | 节点已加入集群,但未启动 group replication |
五、集群管理与优化
1. 集群参数配置
设置所有节点的参数:
jsx
var cluster = dba.getCluster();
cluster.setOption("memberWeight", 50);
cluster.setOption("autoRejoinTries", 5);
设置单个节点的参数:
jsx
cluster.setInstanceOption("mgr-node2:3306", "memberWeight", 75);
cluster.setInstanceOption("mgr-node2:3306", "autoRejoinTries", 10);
memberWeight:节点权重,用于故障转移时的主节点选举,值域 0-100,缺省 50。
2. 节点权重与故障转移
- 权重越高,被选为主节点的可能性越大
- 集群状态 :
statusText: "Cluster is ONLINE and can tolerate up to ONE failure." - 故障转移:当主节点宕机,系统会自动选举权重最高的从节点作为新主
3. 主从切换操作
单主模式切换:
jsx
var cluster = dba.getCluster();
cluster.setPrimaryInstance('mgr-node2:3306');
cluster.status();
单主模式转多主模式:
jsx
var cluster = dba.getCluster();
cluster.switchToMultiPrimaryMode();
多主模式转单主模式:
jsx
cluster.switchToSinglePrimaryMode('mgr-node2:3306');
六、MySQL Router 配置与使用
1. 配置 MySQL Router
bash
mysqlrouter --bootstrap root@mgr-node2:3306 --force --user=root
2. 启动 MySQL Router
bash
mysqlrouter &
3. 连接测试
读写端口(6446:
bash
mysqlsh root@localhost:6446 --sql
只读端口(6447:
bash
mysqlsh root@localhost:6447 --sql
端口说明:MySQL Classic Protocol 使用 6446 和 6447 端口,X Protocol 使用 6448 和 6449 端口。
七、集群故障处理
1. 节点宕机恢复
停掉主节点:
bash
docker stop mgr-node1
查看集群状态:
jsx
cluster.status();
启动主节点:
bash
docker start mgr-node1
集群自动恢复:
- mgr-node1 会自动加入集群
- 状态变为
ONLINE - 集群恢复为
statusText: "Cluster is ONLINE and can tolerate up to ONE failure."
2. 节点重新加入
强制删除节点:
jsx
cluster.removeInstance('root@hostname:3306', {force: true});
重新加入节点:
jsx
cluster.rejoinInstance('root@hostname:3306');
3. 多节点故障恢复
将集群剥离为单节点:
jsx
cluster.forceQuorumUsingPartitionOf('root@hostname:3306');
重新加入其他节点:
jsx
cluster.rejoinInstance('root@hostname2:3306');
cluster.rejoinInstance('root@hostname3:3306');
八、InnoDB ReplicaSet vs InnoDB Cluster
| 特性 | InnoDB ReplicaSet | InnoDB Cluster |
|---|---|---|
| 节点数量 | 至少 2 个 | 至少 3 个 |
| 自动故障转移 | 无 | 有 |
| 读写分离 | 无 | 有 |
| 管理工具 | MySQL Shell | MySQL Shell + MySQL Router |
| 高可用性 | 低 | 高 |
| 配置复杂度 | 简单 | 较复杂 |
| 适用场景 | 简单读写分离 | 高可用生产环境 |
官方建议:尽可能部署 InnoDB Cluster,InnoDB ReplicaSet 具有多个限制,不建议用于生产环境。
九、总结与最佳实践
1. 核心价值总结
- 高可用:3 节点集群允许 1 节点宕机,服务仍可用
- 自动故障转移:节点故障时自动选举新主节点
- 读写分离:MySQL Router 自动将读请求分发到从节点
- 简化管理:通过 MySQL Shell 统一管理集群
- 数据一致性:组复制保证强一致性
2. 最佳实践
- 节点数量:至少 3 个节点(1 主 2 从)实现高可用
- 参数配置 :确保
gtid_mode=ON、enforce_gtid_consistency=ON - 节点权重 :根据业务需求合理设置
memberWeight值 - 监控 :使用
cluster.status()定期检查集群状态 - 测试:定期进行故障转移测试,确保高可用机制正常工作
3. 适用场景
- 电商平台:高并发场景,需要保证服务可用性
- 金融系统:对数据一致性和高可用性要求高的场景
- 大型网站:需要读写分离和高可用的架构
- 分布式系统:作为基础数据服务层,提供高可用数据访问
十、结语
InnoDB Cluster 是 MySQL 8.0 提供的官方高可用解决方案,通过整合 MySQL Router、组复制和 MySQL Shell,为用户提供了一个完整、可靠、易用的高可用架构。相比传统的主从复制,InnoDB Cluster 提供了自动故障转移、读写分离和统一管理能力,大大降低了高可用架构的复杂度。
对于生产环境中的关键业务系统,建议优先考虑使用 InnoDB Cluster,以确保系统的高可用性和数据一致性。在实际部署时,应根据业务需求合理配置节点数量、权重和参数,定期进行故障转移测试,确保高可用机制在关键时刻能够正常工作。
注意:InnoDB Cluster 仅支持 MySQL 8.0.19 及以上版本,部署前请确保 MySQL 版本符合要求。