二十三、Mysql8.0高可用集群架构实战
文章目录
- 一、MySQL InnoDB Cluster
- 1、基本概述
- 2、集群架构
- 3、搭建一主两从InnoDB集群
- 3.1、 安装3个数据库实例
- 3.2、安装mysqlrouter和安装mysqlshell
- 3.2.1、安装mysql-router
- 3.2.2、安装mysql-shell
- 3.3、InnoDB Cluster 初始化
- 3.3.1、参数及权限配置预需求检测
- 3.3.2、初始化InnoDB Cluster相关配置
- 3.4、创建一主两从InnoDB集群
- 3.4.1、集群常用命令
- 3.4.2、进入主节点创建集群
- 3.4.3、添加副本实例
- 小结:完整的集群创建步骤
- 3.4.4、测试数据是否同步
- 3.4.5、测试主从切换
- 3.4.6、更多的常见操作
- 3.4.6.1、参数配置
- 3.4.6.2、配置节点权重
- 3.4.6.3、将节点重新加入集群
- 3.4.6.4、集群多数节点异常,恢复
- 3.4.6.5、集群节点角色切换
- 3.4.6.6、单主模式-指定主节点切换
- 3.4.6.7、单主模式和多主模式相互切换
- 3.4.6.8、销毁集群
- 3.4.6.9、创建集群管理用户
- 3.4.7、使用MySQL Router连接集群
- 3.4.7.1、配置路由器
- 3.4.7.2、启动路由器
- 3.4.7.3、测试
- 二、MySQL InnoDB ReplicaSet
- 1、基本概述
- 2、搭建一主一从的复制集
- 2.1、安装2个数据库实例
- 2.2、配置复制集
- 2.3、配置MySQL Router路由器
- 2.4、测试
一、MySQL InnoDB Cluster
官方文档:https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html
1、基本概述
InnoDB Cluster是MySQL官方实现高可用+读写分离的架构方案,其中包含以下组件
-
MySQL Group Replication:简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举。
-
Mysql Shell:是InnoDB Cluster的管理工具,用来创建和管理集群。
-
Mysql Router:是业务流量入口,支持对MGR的主从角色判断,可以配置不同的端口分别对外提供读写服务,实现读写分离。
MySQL Router与组复制和MySQL Shell高度整合,只有将其与组复制和MySQL Shell共同使用,才能够称为InnoDB Cluster。
2、集群架构
InnoDB Cluster将三个MySQL数据库实例构成一个高可用集群。其中一个实例是具有读/写能力的主要成员,其他两个实例是具有只读能力的次要成员。组复制将数据从主要成员复制到次要成员。MySQL Router将客户端应用程序连接到集群的主要成员。
3、搭建一主两从InnoDB集群
3.1、 安装3个数据库实例
参考:Docker安装MySQL8.0
可以利用docker快速部署3个MySQL实例
主机名(角色) | 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 |
# 创建组复制的网络 保证三个mysql容器之间可以通过容器名访问
docker network create --driver bridge --subnet 172.19.0.0/24 --gateway 172.19.0.1 mgr-networkmkdir -p /mysql/mgr/node1/data /mysql/mgr/node1/conf /mysql/mgr/node1/log
mkdir -p /mysql/mgr/node2/data /mysql/mgr/node2/conf /mysql/mgr/node2/log
mkdir -p /mysql/mgr/node3/data /mysql/mgr/node3/conf /mysql/mgr/node3/log#以mgr-node1配置为例,创建/mysql/mgr/node1/conf/custom.cnf,添加以下配置:
vim /mysql/mgr/node1/conf/custom.cnf
[mysql]
# 设置mysql客户端默认编码
default-character-set=utf8
[mysqld]
#指定sever_id,三个Mysql实例需要分别改为对应的sever_id
server_id=1
# 必须开启GTID支持
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
#对于Group Replication,数据必须存储在InnoDB事务存储引擎中
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"# mgr-node2和mgr-node3同上,注意配置文件路径和修改server_id
vim /mysql/mgr/node2/conf/custom.cnf
[mysql]
# 设置mysql客户端默认编码
default-character-set=utf8
[mysqld]
#指定sever_id,三个Mysql实例需要分别改为对应的sever_id
server_id=2
# 必须开启GTID支持
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
#对于Group Replication,数据必须存储在InnoDB事务存储引擎中
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"vim /mysql/mgr/node3/conf/custom.cnf
[mysql]
# 设置mysql客户端默认编码
default-character-set=utf8
[mysqld]
#指定sever_id,三个Mysql实例需要分别改为对应的sever_id
server_id=3
# 必须开启GTID支持
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
#对于Group Replication,数据必须存储在InnoDB事务存储引擎中
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"#运行mysql容器
# 为了便于测试,启动容器时指定好IP、hostname
docker 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=1docker run -d \
--name mgr-node2 \
--privileged=true \
--restart=always \
--ip 172.19.0.11 \
--hostname mgr-node2 \
--add-host mgr-node1:172.19.0.10 \
--add-host mgr-node3:172.19.0.12 \
--network mgr-network \
-p 3322:3306 \
-v /mysql/mgr/node2/data:/var/lib/mysql \
-v /mysql/mgr/node2/conf:/etc/mysql/conf.d \
-v /mysql/mgr/node2/log:/logs \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai mysql:8.0.27 \
--lower_case_table_names=1docker run -d \
--name mgr-node3 \
--privileged=true \
--restart=always \
--ip 172.19.0.12 \
--hostname mgr-node3 \
--add-host mgr-node1:172.19.0.10 \
--add-host mgr-node2:172.19.0.11 \
--network mgr-network \
-p 3323:3306 \
-v /mysql/mgr/node3/data:/var/lib/mysql \
-v /mysql/mgr/node3/conf:/etc/mysql/conf.d \
-v /mysql/mgr/node3/log:/logs \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai mysql:8.0.27 \
--lower_case_table_names=1# 在宿主机上配置mysql容器的ip和host映射
vim /etc/hosts
172.19.0.10 mgr-node1
172.19.0.11 mgr-node2
172.19.0.12 mgr-node3
所有实例分别配置远程访问
# 以node1为例
docker exec -it mgr-node1 /bin/bash
mysql -u root -p123456
#进入mysql执行
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;
3.2、安装mysqlrouter和安装mysqlshell
MySQL Router是MySQL Proxy的后继产品,它提供了MySQL协议的路由器功能,可以用来实现读写分离、负载均衡和高可用性解决方案。
3.2.1、安装mysql-router
下载地址:https://downloads.mysql.com/archives/router/
# 以centos7为例
wget https://downloads.mysql.com/archives/get/p/41/file/mysql-router-community-8.0.27-1.el7.x86_64.rpm
rpm -ivh mysql-router-community-8.0.27-1.el7.x86_64.rpm
3.2.2、安装mysql-shell
下载地址:https://downloads.mysql.com/archives/shell/
# 以centos7为例
wget https://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.27-1.el7.x86_64.rpm
rpm -ivh mysql-shell-8.0.27-1.el7.x86_64.rpm
# 远程连接mysql
mysqlsh root@192.168.65.223:3321 --js
mysqlsh root@mgr-node1:3306 --js
MySQL Shell 教程: https://downloads.mysql.com/archives/router/
3.3、InnoDB Cluster 初始化
3.3.1、参数及权限配置预需求检测
在添加实例到集群中前,使用该方法检查实例配置是否满足InnoDB 集群要求。
mysqlsh root@192.168.65.223:3321 --js
// 检查实例是否符合InnoDB Cluster的参数及权限配置要求
dba.checkInstanceConfiguration('root@mgr-node1:3306')
dba.checkInstanceConfiguration('root@mgr-node2:3306')
dba.checkInstanceConfiguration('root@mgr-node3:3306')
如果验证通过返回ok。
如果验证没通过,比如出现下面的日志提示,需要mysql实例开启gtid和指定server_id
搭建InnoDB Cluster需要满足的要求如下:
InnoDB集群使用了Group Replication,因此必须满足使用组复制的要求。
具体可以参考https://dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html。
其中比较重要的几点有:
-
必须开启二进制日志,并且日志格式为ROW,即–log-bin和binlog_format=row(默认)。
-
必须开启副本更新日志,即log_replica_updates=ON(默认)。
-
必须开启GTID,即gtid_mode=ON和enforce_gtid_consistency=ON。
-
存储引擎只 能使用InnoDB。最好禁用其他存储引擎:
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
- 从 8.0.23开始,集群中的实例要启用并行复制。需要配置以下系统变量:
binlog_transaction_dependency_tracking=WRITESET
slave_preserve_commit_order=ON
slave_parallel_type=LOGICAL_CLOCK
transaction_write_set_extraction=XXHASH64
3.3.2、初始化InnoDB Cluster相关配置
// 对实例配置InnoDB Cluster相关参数
dba.configureInstance('root@mgr-node1:3306')
dba.configureInstance('root@mgr-node2:3306')
dba.configureInstance('root@mgr-node3:3306')
3.4、创建一主两从InnoDB集群
3.4.1、集群常用命令
#会列出dba相关指令
dba.help();
#列出详细指令的用法
dba.help('deploySandboxInstance');
#检查节点配置实例,用于加入cluster之前
dba.checkInstanceConfiguration("root@hostname:3306");
#节点初始化
dba.configureInstance('root@hostname:3306');
#重启集群
dba.rebootClusterFromCompleteOutage('myCluster');
#会列出集群相关指令
cluster.help();
#创建集群
var cluster = dba.createCluster('myCluster');
#获取当前集群实例
var cluster = dba.getCluster('myCluster');
查看集群状态
cluster.status();
#检查cluster节点状态
cluster.checkInstanceState("root@hostname:3306") ;
#增加节点
cluster.addInstance("root@hostname:3306") ;
#删除节点
cluster.removeInstance("root@hostname:3306") ;
#强制删除节点
cluster.removeInstance('root@hostname:3306',{force:true});
# 状态为missing的节点可以重新加入集群
cluster.rejoinInstance("root@hostname:3306")
#解散集群
cluster.dissolve({force:true}) ;
#集群描述
cluster.describe();
3.4.2、进入主节点创建集群
初始化完第一个实例后,就可以创建集群了。
# 进入主节点创建集群
mysqlsh root@192.168.65.223:3321 --js
# 创建一个 cluster,命名为 'myCluster'
var cluster = dba.createCluster('myCluster');
# 创建成功后,查看cluster状态
cluster.status();
当前集群的状态如下
3.4.3、添加副本实例
添加副本实例到创建好的集群。
#初始化第二个和第三个实例:
cluster.addInstance('root@mgr-node2:3306');
cluster.addInstance('root@mgr-node3:3306');
#查看cluster状态
cluster.status();
如果提示副本实例的GTID与集群不一致,选择通过Clone方式覆盖副本实例上的数据即可。
小结:完整的集群创建步骤
#进入主节点
mysqlsh root@mgr-node1:3306 --js#mgr-node1
# 参数权限检查
dba.checkInstanceConfiguration('root@mgr-node1:3306');
# 初始化
dba.configureInstance('root@mgr-node1:3306');
# 创建集群
var cluster = dba.createCluster('myCluster');
#查看cluster状态
cluster.status();#mgr-node2
# 参数权限检查
dba.checkInstanceConfiguration('root@mgr-node2:3306');
# 初始化
dba.configureInstance('root@mgr-node2:3306');
# 添加副本
cluster.addInstance('root@mgr-node2:3306');#mgr-node3
# 参数权限检查
dba.checkInstanceConfiguration('root@mgr-node3:3306');
# 初始化
dba.configureInstance('root@mgr-node3:3306');
# 添加副本
cluster.addInstance('root@mgr-node3:3306');#查看cluster状态
cluster.status();
搭建一主两从集群架构最终效果如下:
注意到集群状态已变为"status": “OK"和"statusText”: “Cluster is ONLINE and can tolerate up to ONE failure.”。
集群节点状态:
-
ONLINE - 节点状态正常。
-
OFFLINE - 实例在运行,但没有加入任何Cluster。
-
RECOVERING - 实例已加入Cluster,正在同步数据。
-
ERROR - 同步数据发生异常。
-
UNREACHABLE - 与其他节点通讯中断,可能是网络问题,可能是节点crash。
-
MISSING - 节点已加入集群,但未启动group replication
3.4.4、测试数据是否同步
#主节点 mgr-node1
[root@192-168-65-223 ~]# docker exec -it mgr-node1 bash
root@mgr-node1:/# mysql -uroot -p123456
mysql>
create database test;
use test;
create table t(x int primary key auto_increment,y int);
insert into t(x,y) value(1,1);
注意:如果创建表没有设置主键,会抛出错误:ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
# 查看其他节点,数据是否同步
[root@192-168-65-223 ~]# docker exec -it mgr-node2 bash
root@mgr-node2:/# mysql -uroot -p123456
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> select * from t;
+---+------+
| x | y |
+---+------+
| 1 | 1 |
+---+------+
1 row in set (0.00 sec)
3.4.5、测试主从切换
#停掉主节点
[root@192-168-65-223 ~]# docker stop mgr-node1# 连接到mgr-node2
MySQL mgr-node1:3306 ssl JS > \connect root@mgr-node2:3306
# 获取集群实例MySQL mgr-node2:3306 ssl JS > var cluster=dba.getCluster();
# 查看集群状态
MySQL mgr-node2:3306 ssl JS > cluster.status()
{"clusterName": "myCluster", "defaultReplicaSet": {"name": "default", "primary": "mgr-node2:3306", "ssl": "REQUIRED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.", "topology": {"mgr-node1:3306": {"address": "mgr-node1:3306", "memberRole": "SECONDARY", "mode": "n/a", "readReplicas": {}, "role": "HA", "shellConnectError": "MySQL Error 2003: Could not open connection to 'mgr-node1:3306': Can't connect to MySQL server on 'mgr-node1:3306' (113)", "status": "(MISSING)"}, "mgr-node2:3306": {"address": "mgr-node2:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}, "mgr-node3:3306": {"address": "mgr-node3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "mgr-node2:3306"
可以看到mgr-node2升级为主节点
# 启动mgr-node1节点
[root@192-168-65-223 ~]# docker start mgr-node1
# 查看集群状态,发现mgr-node1正在恢复,最终正常MySQL mgr-node2:3306 ssl JS > cluster.status()
{"clusterName": "myCluster", "defaultReplicaSet": {"name": "default", "primary": "mgr-node2:3306", "ssl": "REQUIRED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.", "topology": {"mgr-node1:3306": {"address": "mgr-node1:3306", "instanceErrors": ["NOTE: group_replication is stopped."], "memberRole": "SECONDARY", "memberState": "OFFLINE", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "(MISSING)", "version": "8.0.27"}, "mgr-node2:3306": {"address": "mgr-node2:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}, "mgr-node3:3306": {"address": "mgr-node3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "mgr-node2:3306"
}
MySQL mgr-node2:3306 ssl JS > cluster.status()
{"clusterName": "myCluster", "defaultReplicaSet": {"name": "default", "primary": "mgr-node2:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": {"mgr-node1:3306": {"address": "mgr-node1:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}, "mgr-node2:3306": {"address": "mgr-node2:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}, "mgr-node3:3306": {"address": "mgr-node3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.27"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "mgr-node2:3306"
}
3.4.6、更多的常见操作
3.4.6.1、参数配置
可以用cluster.options()查看当前集群的配置属性,集群参数配置分为两种方式:
-
cluster.setOption() 用来设置所有节点的参数
-
cluster.setInstanceOption() 用来对指定节点配置属性
# 将所有节点的权重都改为50
var cluster = dba.getCluster()
cluster.setOption("memberWeight",50)
# 重新加入集群重试次数改为5次
cluster.setOption("autoRejoinTries",5)# 将其中一个节点的权重改为75
cluster.setInstanceOption("mgr-node2:3306","memberWeight",75)
# 重新加入集群重试次数改为10次
cluster.setInstanceOption("mgr-node2:3306","autoRejoinTries",10)
3.4.6.2、配置节点权重
memberWeight选项的值域为0到100之间的整数,缺省值为50。该值是故障转移时自动选举主节点的百分比权重,具有较高memberWeight值的实例更有可能在单主群集中被选为主节点
// 查看集群的参数配置(包括memberWeight优先级配置)
cluster.options()// 在集群创建时配置
dba.createCluster('myCluster', {memberWeight:75}) // 第一个节点配置方式
var cluster = dba.getCluster()
cluster.addInstance('mgr-node2:3306',{memberWeight:50})
cluster.addInstance('mgr-node3:3306',{memberWeight:25})// 在集群创建完成后修改权重
var cluster = dba.getCluster()
cluster.setInstanceOption('mgr-node1:3306','memberWeight',100)
cluster.setInstanceOption('mgr-node2:3306','memberWeight',50)
cluster.setInstanceOption('mgr-node3:3306','memberWeight',25)
3.4.6.3、将节点重新加入集群
状态为mssing的节点,通常是组复制关闭或中断状态,可以用cluster.rejoinInstance()重新加入集群,会重新对该节点设置MGR相关参数(持久化到mysqld-auto.conf中)
cluster.removeInstance('root@hostname:3306',{force:true});
如果一些参数做了修改,如server_uuid变更,导致rejoin失败,则需要将节点从集群中删除后重新加入
cluster.removeInstance("root@hostname:3306",{force:true})
cluster.rescan()
cluster.addInstance("root@hostname:3306")
3.4.6.4、集群多数节点异常,恢复
当集群多个节点异常,则失去了仲裁机制,剩下的一个节点
// 将集群剥离为单节点运行
JS > cluster.forceQuorumUsingPartitionOf("root@hostname:3306")// 重新加另外2个节点加入
JS > cluster.rejoinInstance("root@hostname2:3306")
JS > cluster.rejoinInstance("root@hostname3:3306")
3.4.6.5、集群节点角色切换
在MGR的管理下提供了一下3种方式进行角色切换,mysqlsh对其进行了封装调用
-
group_replication_set_as_primary(member_uuid);
- cluster.setPrimaryInstance(“homename:3306”)
-
group_replication_switch_to_single_primary_mode()
- cluster.switchToSinglePrimaryMode(“homename:3306”)
-
group_replication_switch_to_multi_primary_mode()
- cluster.switchToMultiPrimaryMode()
3.4.6.6、单主模式-指定主节点切换
var cluster = dba.getCluster()
cluster.setPrimaryInstance('homename:3306')
cluster.status()
3.4.6.7、单主模式和多主模式相互切换
// 切换为多主模式
var cluster = dba.getCluster()
cluster.switchToMultiPrimaryMode()// 指定明确的主节点将多主模式切换为单主模式
cluster.switchToSinglePrimaryMode("homename:3306")
将单主模式切换为多主模式的效果
3.4.6.8、销毁集群
删除与群集关联的所有元数据和配置,并禁用实例上的组复制,但不会删除在实例之间复制的任何数据。要再次创建集群,使用dba.createCluster()
var cluster = dba.getCluster()
cluster.dissolve()
3.4.6.9、创建集群管理用户
cluster.setupAdminAccount('fox')
# 经典MySQL协议连接
mysqlsh --mysql -hmgr-node1 -ufox
# X协议连接
mysqlsh --mysqlx -hmgr-node1 -ufox
3.4.7、使用MySQL Router连接集群
3.4.7.1、配置路由器
mysqlrouter --bootstrap root@mgr-node2:3306 --force --user=root
#或者指定host
mysqlrouter --bootstrap root@mgr-node2:3306 --force --user=root --report-host mgr
注意,如果用户之前为该实例配置过路由,则可以通过指定force选项强制引导启动。
上面的内容是引导启动路由器时输出的信息,信息提示,MySQL经典协议使用6446端口和6447端口,X协议使用6448端口和6449端口,每种协议使用的两个端口分别用于读写和只读。
在一个运行的集群中,AdminAPI 可以引导多个路由器。用户可以使用cluster.listRouters()方法显示所有注册的路由器列表。
3.4.7.2、启动路由器
mysqlrouter &
路由器已经成功启动。现在,使用MySQL Shell连接路由器进行验证。
#连接mysqlrouter
[root@192-168-65-223 ~]# mysqlsh root@localhost:6446 --sql
MySQL localhost:6446 ssl SQL > use test;
MySQL localhost:6446 ssl test SQL > select * from t;
查看集群成员信息
MySQL localhost:6446 ssl test SQL > select * from performance_schema.replication_group_members;
3.4.7.3、测试
测试读写端口6446
用户可以通过连接本机的6446端口连接到MySQL实例
6446为读写端口,也可以插入数据
测试只读端口6647:插入数据报错
二、MySQL InnoDB ReplicaSet
1、基本概述
MySQL Innodb Cluster = MySQL Shell + MySQL Router + MySQL Group Replication(MGR),全程由 MySQL Shell 来管理操作 MGR 的聚合套件。MySQL 8.0.19 发布后,这种组合延伸到 MySQL Replication(主从复制),也就是 MySQL Shell + MySQL Router + MySQL Replication。
InnoDB ReplicaSet至少由两个MySQL服务器实例组成,并提供用户熟知的主从复制功能,例如读取横向扩展和数据安全性。InnoDB ReplicaSet使用以下MySQL技术。
-
MySQL Shell:MySQL的高级客户端、管理工具,可以用来管理复制集。
-
MySQL复制:一组MySQL实例,通过复制能够提供可用性和异步读取的横向扩展。
-
MySQL Router:一种轻量级的中间件,可在应用程序和InnoDB ReplicaSet之间提供透明的路由。InnoDB ReplicaSet的接口类似于InnoDB Cluster,用户可以利用MySQL Shell使用MySQL实例和MySQL Router。
与InnoDB集群相比,InnoDB ReplicaSet具有多个限制,因此,官方建议尽可能部署InnoDB群集。通常,InnoDB ReplicaSet本身不能提供高可用性。InnoDB ReplicaSet的限制包括:
-
没有自动故障转移。如果主服务器不可用,则需要使用AdminAPI手动触发故障转移,然后才能再次进行任何更改。但是,辅助实例仍然可用于读取。
-
无法防止因意外停止或不可用而导致部分数据丢失。暂停之前尚未应用的事务可能会丢失。
-
无法防止崩溃或不可用后出现不一致情况。如果故障转移在辅助节点仍可用的情况下提升了辅助节点(例如,由于网络分区),则可能会因脑裂而引起不一致。
2、搭建一主一从的复制集
2.1、安装2个数据库实例
参考:Docker安装MySQL8.0
可以利用docker快速部署2个MySQL实例
主机名(角色) | server_id | 宿主机IP | 容器固定IP | DB Port |
---|---|---|---|---|
rs-node1(primary) | 21 | 192.168.65.223 | 172.20.0.20 | 3331>3306 |
rs-node2(Secondary) | 22 | 192.168.65.223 | 172.20.0.21 | 3332>3306 |
# 创建组复制的网络 保证三个mysql容器之间可以通过容器名访问
docker network create --driver bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 rs-networkmkdir -p /mysql/rs/node1/data /mysql/rs/node1/conf /mysql/rs/node1/log
mkdir -p /mysql/rs/node2/data /mysql/rs/node2/conf /mysql/rs/node2/log#以rs-node1配置为例,创建/mysql/rs/node1/conf/custom.cnf,添加以下配置:
vim /mysql/rs/node1/conf/custom.cnf
[mysql]
# 设置mysql客户端默认编码
default-character-set=utf8
[mysqld]
#指定sever_id,多个Mysql实例需要分别改为对应的sever_id
server_id=21
# 必须开启GTID支持
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# rs-node2同上,注意配置文件路径和修改server_id
vim /mysql/rs/node2/conf/custom.cnf
[mysql]
# 设置mysql客户端默认编码
default-character-set=utf8
[mysqld]
#指定sever_id,多个Mysql实例需要分别改为对应的sever_id
server_id=22
# 必须开启GTID支持
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#运行mysql容器
# 为了便于测试,启动容器时指定好IP、hostname
docker run -d \
--name rs-node1 \
--privileged=true \
--restart=always \
--ip 172.20.0.20 \
--hostname rs-node1 \
--add-host rs-node2:172.20.0.21 \
--network rs-network \
-p 3331:3306 \
-v /mysql/rs/node1/data:/var/lib/mysql \
-v /mysql/rs/node1/conf:/etc/mysql/conf.d \
-v /mysql/rs/node1/log:/logs \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai mysql:8.0.27 \
--lower_case_table_names=1docker run -d \
--name rs-node2 \
--privileged=true \
--restart=always \
--ip 172.20.0.21 \
--hostname rs-node2 \
--add-host rs-node1:172.20.0.20 \
--network rs-network \
-p 3332:3306 \
-v /mysql/rs/node2/data:/var/lib/mysql \
-v /mysql/rs/node2/conf:/etc/mysql/conf.d \
-v /mysql/rs/node2/log:/logs \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai mysql:8.0.27 \
--lower_case_table_names=1# 在宿主机上配置mysql容器的ip和host映射
vim /etc/hosts
172.20.0.20 rs-node1
172.20.0.21 rs-node2
所有实例分别配置远程访问
# 以node1为例
docker exec -it rs-node1 /bin/bash
mysql -u root -p123456
#进入mysql执行
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;
2.2、配置复制集
1)初始化主节点,创建复制集
#进入主节点
mysqlsh root@rs-node1:3306 --js
# 初始化
dba.configureReplicaSetInstance('root@rs-node1:3306')
# 创建复制集,使用异步复制
var rs = dba.createReplicaSet("myrs")
#查看状态
rs.status()
2)添加副本节点
#将实例添加到复制集
rs.addInstance('root@rs-node2:3306')
测试数据是否同步
#主节点 rs-node1
[root@192-168-65-223 ~]# docker exec -it rs-node1 bash
root@mgr-node1:/# mysql -uroot -p123456
mysql>
create datebase test;
use test;
create table t(x int primary key auto_increment,y int);
insert into t(x,y) value(1,1);
select * from t;# 进入从节点rs-node2,查看数据是否同步过来
[root@192-168-65-223 ~]# docker exec -it rs-node2 bash
root@rs-node2:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1596
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2021, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> select * from t;
+---+------+
| x | y |
+---+------+
| 1 | 1 |
+---+------+
1 row in set (0.00 sec)
2.3、配置MySQL Router路由器
[root@192-168-65-223 ~]# mysqlrouter --bootstrap root@rs-node1:3306 --force --user=root
重启Mysql Router
[root@192-168-65-223 ~]# ps -ef|grep mysqlrouter
root 16993 14238 6 11:30 pts/1 00:18:01 mysqlrouter
root 21637 14178 0 16:22 pts/0 00:00:00 grep --color=auto mysqlrouter
[root@192-168-65-223 ~]# kill -9 16993
# 启动Mysql Router
[root@192-168-65-223 ~]# mysqlrouter &
2.4、测试
用户可以通过连接本机的6446端口连接到MySQL实例
[root@192-168-65-223 ~]# mysqlsh root@localhost:6446 --sql
# 可以查询到插入的测试数据MySQL localhost:6446 ssl SQL > select * from test.t;
+---+---+
| x | y |
+---+---+
| 1 | 1 |
+---+---+
相关文章:

二十三、Mysql8.0高可用集群架构实战
文章目录 一、MySQL InnoDB Cluster1、基本概述2、集群架构3、搭建一主两从InnoDB集群3.1、 安装3个数据库实例3.2、安装mysqlrouter和安装mysqlshell3.2.1、安装mysql-router3.2.2、安装mysql-shell 3.3、InnoDB Cluster 初始化3.3.1、参数及权限配置预需求检测3.3.2、初始化I…...

docker file 精简规则
在编写 Dockerfile 时,精简规则不仅有助于减小镜像大小,还能提高构建速度和可维护性。以下是一些常见的精简 Dockerfile 规则: 1. 尽量合并 RUN 指令 每个 RUN 指令会产生一个新的镜像层,因此多个命令可以合并为一个 RUN 指令&a…...

前端加密方式详解与选择指南
在当今数字化时代,前端数据安全的重要性日益凸显。本文将深入探讨前端加密的多种方式,为你提供选择适合项目加密方式的实用策略,并分享一些实际案例及相应代码。 一、前端加密方式汇总 (一)HTTPS 加密 HTTPS 是在 H…...

【React】条件渲染——逻辑与运算符
条件渲染——逻辑与&&运算符 你会遇到的另一个常见的快捷表达式是 JavaScript 逻辑与(&&)运算符。在 React 组件里,通常用在当条件成立时,你想渲染一些 JSX,或者不做任何渲染。 function Item({ nam…...

MATLAB中eig函数用法
目录 语法 说明 示例 矩阵特征值 矩阵的特征值和特征向量 排序的特征值和特征向量 左特征向量 不可对角化(亏损)矩阵的特征值 广义特征值 病态矩阵使用 QZ 算法得出广义特征值 一个矩阵为奇异矩阵的广义特征值 eig函数的功能是求取矩阵特征值…...

Chrome(谷歌浏览器中文版)下载安装(Windows 11)
目录 Chrome_10_30工具下载安装 Chrome_10_30 工具 系统:Windows 11 下载 官网:https://chrome.google-zh.com/,点击立即下载 下载完成(已经下过一遍所以点了取消) 安装 解压,打开安装包 点击下一步…...

Linux 配置JDK
文章目录 一、下载Oracle-JDK1.1、如何正确的下载JDK 二、配置JDK环境变量2.1 环境变量配置2.1.1、修改vim /etc/profile 添加jdk的路径 一、下载Oracle-JDK 1.1、如何正确的下载JDK 首先我要安装的是oracle-jdk,这个时候什么地方都不要去,就去oracle的…...

目前主流的人工智能学习框架有哪些?
随着人工智能(AI)技术的蓬勃发展,越来越多的AI学习框架相继推出,成为开发者、研究人员和企业构建机器学习(ML)和深度学习(DL)模型的首选工具。AI学习框架不仅提供了丰富的工具库和函…...

100种算法【Python版】第57篇——贝叶斯优化算法
本文目录 1 算法说明2 贝叶斯优化的步骤3 算法应用1:目标函数最大值4 算法应用2:确定最佳试验参数1 算法说明 贝叶斯优化是一种旨在优化黑箱目标函数的策略,通常适用于评估代价高昂或时间消耗长的函数。它利用贝叶斯统计方法来构建目标函数的概率模型,进而指导下一步的采样…...

在Ubuntu 上实现 JAR 包的自启动
在 Ubuntu 上实现 JAR 包的自启动,可以通过以下几种方法: 方法一:使用 systemd 创建一个服务文件: 在 /etc/systemd/system/ 目录下创建一个新的服务文件,例如 myapp.service: sudo nano /etc/systemd/sys…...

【智能算法应用】哈里斯鹰算法优化二维栅格路径规划问题
摘要 本文研究了基于哈里斯鹰优化算法(Harris Hawks Optimization, HHO)的二维栅格路径规划方法。HHO算法模拟哈里斯鹰的猎食行为,通过迭代搜索过程找到从起点到终点的最优路径,避开栅格中的障碍物。实验结果表明,HHO…...

单品年销10亿!看麻辣王子是如何布局软文营销为品牌赋能的?
说到辣条,除了大家熟知的卫龙之外,还有一个不得不提的品牌就是——麻辣王子。 作为来自辣条发源地湖南平江的老牌辣条企业,麻辣王子近几年通过打造品牌,积极破圈,2023年凭借一款单品狂揽超10亿年销售额,稳…...

【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
博主说明:本文项目编号 T 062 ,文末自助获取源码 \color{red}{T062,文末自助获取源码} T062,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...

C++:模拟实现STL的string
目录 一.实现string类 1.string的构造及析构 2.string类的遍历 3.string类的插入和删除 4.string类的空间处理 5.string类的查找 6.string类的输出和输入 7.string类的常用判断 二.整体代码 1.string.h 2.string.cpp 一.实现string类 在前一节中我们了解了STL中stri…...

【Python TensorFlow】入门到精通
TensorFlow 是一个开源的机器学习框架,由 Google 开发,广泛应用于机器学习和深度学习领域。本篇将详细介绍 TensorFlow 的基础知识,并通过一系列示例来帮助读者从入门到精通 TensorFlow 的使用。 1. TensorFlow 简介 1.1 什么是 TensorFlow…...

数据结构:七种排序及总结
文章目录 排序一插入排序1直接插入排序2希尔排序二选择排序3直接选择排序4堆排序三 交换排序5冒泡排序6快速排序四 归并排序7归并排序源码 排序 我们数据结构常见的排序有四大种,四大种又分为七小种,如图所示 排序:所谓排序,就是…...

【安当产品应用案例100集】030-使用企业微信登录Windows,实现工作电脑与业务系统登录方式统一
随着越来越多的企业信息系统从intranet开放到internet,企业员工的办公接入方式也越发多样,信息系统面临的数据安全问题也呈现爆发的趋势。一些大企业,比如Google、Microsoft、Huawei有强大的开发能力、IT能力,可以构建出自己的零信…...

大数据数据存储层MemSQL, HBase与HDFS
以下是对 MemSQL、HBase 和 HDFS 的详细介绍,这些工具在分布式数据存储和处理领域有着重要作用。 1. MemSQL MemSQL(现称为 SingleStore)是一种分布式内存数据库,兼具事务处理(OLTP)和分析处理(OLAP)的能力,专为高性能实时数据处理设计。 1.1 核心特点 内存优先存储…...

【HarmonyOS】鸿蒙应用设置控件通用样式AttributeModifier, @Styles
【HarmonyOS】鸿蒙应用设置控件通用样式AttributeModifier, Styles 前言 在鸿蒙中UI开发经常需要对控件样式进行统一的封装,在API早前版本,一般是通过 Styles进行样式封装复用: Entry Component struct Index {build() {Column(…...

Scala IF...ELSE 语句
Scala IF...ELSE 语句 Scala 是一种多范式的编程语言,它结合了面向对象和函数式编程的特点。在 Scala 中,if...else 语句是一种基本且常用的控制结构,用于根据条件执行不同的代码块。与 Java 或 Python 等其他语言中的 if...else 语句类似&a…...

快速上手vue3+js+Node.js
安装Navicat Premium Navicat Premium 创建一个空的文件夹(用于配置node) 生成pakeage.json文件 npm init -y 操作mysql npm i mysql2.18.1 安装express搭建web服务器 npm i express4.17.1安装cors解决跨域问题 npm i cors2.8.5创建app.js con…...

06 网络编程基础
目录 1.通信三要素 1. IP地址(Internet Protocol Address) 2. 端口号(Port Number) 3. 协议(Protocol) 2.TCP与UDP协议 三次握手(Three-Way Handshake) 四次挥手(…...

Python 的 FastApi 如何在request 重复取request.body()
需求背景: 需要再中间件中获取body 中的信息 但是 又想要在之后 还可以重复取 这个body 因为有的接口写法是直接从body中获取参数,然而这个body是数据流的形式,一旦取一次就导致后面取不到里面的值了 。 解决方式: 1.保存请求体: 在中间件中读取请求…...

qt QFontDialog详解
1、概述 QFontDialog 是 Qt 框架中的一个对话框类,用于选择字体。它提供了一个可视化的界面,允许用户选择所需的字体以及相关的属性,如字体样式、大小、粗细等。用户可以通过对话框中的选项进行选择,并实时预览所选字体的效果。Q…...

AI时代,通才可能会占据更有利的地位
在AI时代,通才不仅有生存的可能,而且根据多个参考内容,他们实际上可能占据更有利的地位。以下几点解释了为什么通才在人工智能时代具有重要性和生存空间: 适应性和灵活性:通才因其广泛的知识基础和跨领域的技能&#x…...

qt QHeaderView详解
1、概述 QHeaderView 是 Qt 框架中的一个类,它通常作为 QTableView、QTreeView 等视图类的一部分,用于显示和管理列的标题(对于水平头)或行的标题(对于垂直头)。QHeaderView 提供了对这些标题的排序、筛选…...

探索PickleDB:Python中的轻量级数据存储利器
文章目录 探索PickleDB:Python中的轻量级数据存储利器1. 背景:为什么选择PickleDB?2. PickleDB是什么?3. 如何安装PickleDB?4. 简单的库函数使用方法创建和打开数据库设置数据获取数据删除数据保存数据库 5. 应用场景与…...

yocto下编译perf失败的解决方法
文章目录 问题分析库没有安装?文件缺少?解决参考问题 在新环境使用yocto编译镜像时,发现最后一直编译不过perf,具体的编译提示错误如下 ERROR: perf-1.0-r9 do_compile: oe_runmake failed ERROR: perf-1.0-r9 do_compile: Execution of /home/ub-1001/work/as66/imx8LBV…...

丹摩征文活动|详解 DAMODEL(丹摩智算)平台:为 AI 开发者量身打造的智算云服务
本文 什么是 DAMODEL(丹摩智算)?DAMODEL 的平台特性快速上手 DAMODEL 平台GPU 实例概览创建 GPU 云实例 储存选项技术支持与社区服务结语 在人工智能领域的飞速发展中,计算资源与平台的选择变得尤为重要。为了帮助 AI 开发者解决高…...

ORACLE _11G_R2_ASM 常用命令
--------查看磁盘组,(空间情况) select name,state,free_mb,total_mb,usable_file_mb from v$asm_diskgroup; --------查看磁盘情况 select GROUP_NUMBER,free_mb,total_mb,disk_number,MOUNT_STATUS,mode_status, HEADER_STATUS,name,PATH from v$asm_disk order …...