- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
高可用集群的基本特点 。
负载均衡 / 读写分离 / 故障转移 本文以此为目标,利用 mysql-shell、mysql-router,基于 docker 的环境架构(篇幅太长,内容多了点儿).
名词 | 解释 |
---|---|
GR | Group Replication;集群间的主从节点数据复制,利用 gtid、binlog 等确保所有节点数据的一致。 |
DDL | Data Definition Language;操作库本身的语句。如 CREATE/ALTER/DROP等语句;自动提交当前事务;不能回滚。 |
DML | Data Manipulation Language;针对数据的操作,如 CRUD,可回滚。 |
本文主要阐述内容:
名称 | 标签 | 角色 |
---|---|---|
Rockylinux | 9.1 | 本次整体测试虚拟机;可参考: https://rockylinux.org |
mysql-shell | 8.0.31 | 用来管理集群 |
mysql-router | 8.0.31 | 集群路由服务 |
docker | 20.10.22 | 集群服务容器载体 |
docker image:oraclelinux | 9-slim | 用来部署 mysql-router 的镜像 |
docker image:mysql | 8.0.31 | 集群实例服务镜像 |
mysql-cli | 8.0.31 | 用来测试验证连接的客户端 |
环境架构图示例 :
应用安装层次图 :
- docker 的安装在这里省略。 - 网络地址全部使用 hostname 代替 IP 相互通信。 - 所有 MySQL 系相关的应用版本计划统一为 8.0.31。 - 所有 MySQL 涉及到的账号,为了测试便捷,以下都用 root / 统一密码操作.
mysql image :利用官方提供的镜像,后续运行容器作为集群的节点 。
oraclelinux image :官方提供的系统镜像,后续为运行 mysql-router 的容器 。
# 拉取oraclelinux系统镜像
docker pull oraclelinux:9-slim
# 拉取MySQL官网提供的镜像
docker pull mysql:8.0.31
集群,当然建议固定 ip,甚至配置集群 hosts;这对于集群内部网络高并发下是很有必要的网络优化.
为此,这里单独创建一个虚拟网络,后续应用到集群中。 (计划本次测试不涉及跨主机的网络转发) 。
# 这里创建一个名称为 br-mysql-clus 的自定义网络,计划集群所有节点处在同一网段下
docker network create --subnet=12.12.0.0/24 --gateway=12.12.0.254 br-mysql-clus
计划集群中的每个节点都用固定 IP,并指明 hostname,以 hostname 相互通信 (这在集群中提升了通信的效率) .
计划所有的容器 hosts 文件都绑定到 Linux VM 的 /etc/hosts ;所以主机 hosts 设置所有节点的 IP > hostname:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# 追加集群各节点的 IP > hostname
# 以下定义,为后续容器的运行做准备
12.12.0.1 mc1 # mysql cluster node 1
12.12.0.2 mc2 # mysql cluster node 2
12.12.0.3 mc3 # mysql cluster node 3
12.12.0.5 mr # mysql router
如果不配置以下各项,后续组建集群的 shell 会逐一列出不符合集群要求的项,并提醒完成必须的配置.
server_id :集群各节点唯一标识,必须为数字型;基于此配置会自动生成配置项 server_uuid 的值.
gtid_mode / dnforce_gtid_consistency :开启组复制 / 并保持事务的一致性,这个很重要.
group_replication_single_primary_mode :本次计划的 单主多从 集群模式.
binlog_transaction_dependency_tracking :集群同步数据时更精确的事务处理方式.
group_replication_group_name :统一的名称才可识别为属于同一个集群.
[mysqld]
# 各节点的唯一识别,各节点cnf唯一不同之处,只能是数字
server_id = 1
# 开启组复制的集群数据同步功能
gtid_mode = ON
enforce_gtid_consistency = ON
# 指明单主多从模式
loose-group_replication_single_primary_mode = ON
loose-binlog_transaction_dependency_tracking = WRITESET
# 集群名称,必为有效的UUID
loose-group_replication_group_name = "a53e2dec-a5fe-11ed-99b8-080027c5c3a3"
什么是 GTID 。
全局事务标识符;GTID 是创建的唯一标识符,基于事务的数据复制,可以识别和跟踪源服务器上提交的每个事务,在源和拓扑服务器上均唯一;它在源服务器上提交并由任何副本应用,源和副本之间始终保留GTID,只要在源上提交的所有事务也在副本上提交,在源上提交的事务只能在副本上应用一次,就可以保证两者之间的一致性.
配置项说明解释:
group_replication_start_on_boot :节点加入集群时,自动开始复制 Master 数据功能,以保持节点间数据一致.
group_replication_bootstrap_group :集群启动后是否作为 Master 节点,自动开始RG;建议都设为 OFF.
group_replication_local_address :集群内各节点之间,当前节点对外的通讯地址.
group_replication_group_seeds :集群启动时,组建的基本节点.
[mysqld]
# 启动后自动运行组复制,默认=ON
#loose-group_replication_start_on_boot = ON
# 重启后的集群以哪个实例的数据为准的复制同步过程
#loose-group_replication_bootstrap_group = OFF
# 明确本节点的对外通信地址(不是必须,shell脚本可覆盖代替)
# 当 communication_stack = MYSQL 时,以下端口只能3306
# 当 communication_stack = XCOM 时,以下端口建议33061
#loose-group_replication_local_address="{host}:3306"
# 种子节点,由每个节点的通信地址组成(不是必须,shell脚本可覆盖代替)
#loose-group_replication_group_seeds="{host}:3306,{host}:3306,{host}:3306"
需要注意的配置项 group_replication_bootstrap_group 。
假设1:所有节点都设为 OFF,重启的集群不会自动开始组复制(GR)功能 假设2:多节点设为 ON,系统分不清以哪个节点为基准的组复制(GR)功能(脑裂现象) 假设3:固定一个节点设为 ON,此节点的数据在集群中不一定是最完整的 。
所以,重启后的集群,人为的选择 Master,手动启动组复制(GR)最为妥当 。
方案1:集群启动前,选好一台 ON 作为 Master,集群启动后,需改为 OFF 方案2:在被人为认定的 Master 主机上,手动启动GR,如下脚本: mysql> SET GLOBAL group_replication_bootstrap_group = ON; mysql> START GROUP_REPLICATION USER='***', PASSWORD='***'; mysql> SET GLOBAL group_replication_bootstrap_group = OFF,
以下默认值都已符合集群运行的基本要求,或者不同场景,您需要不同的配置.
log_bin :二进制日志,包括所有(DDL/DML)脚本的执行记录,用于实时主从数据同步/数据恢复.
log_replica_updates :同步过来的二进制更新日志,也需要记录到自己的二进制日志中;便于灾难时的恢复.
binlog_format :数据同步日志记录的程度;一般的/更细的/混合的;当然ROW更细的日志会带来更庞大的空间占用.
[mysqld]
#log_bin = ON # default = ON
#log_replica_updates = ON # default = ON
#binlog_format = ROW # default = ROW
#master_info_repository = TABLE # default = TABLE
#relay_log_info_repository = TABLE # default = TABLE
什么是 binlog 。
Binary Log;以二进制的形式记录了对于数据库的变更过程。 binlog可设定单文件大小,过期时间等;多用于:数据恢复、主从同步.
binlog 的三种记录方式: STATEMENT:能够记录大多数的脚本变更过程; ROW:记录所有的脚本变更细节,空间占用过大; MIXED:不同方式压缩记录所有脚本的变更,确保数据的一致性、准确性.
[mysqld]
# 持久化设置,默认=NO
# 参数或配置保存起来,如:组建时产生的账户密码,重启后依然有效
#persisted_globals_load = ON
# 选举权重百分比,默认=50,正序排列优先顺序
#loose-group_replication_member_weight = 50
# 新版 默认=MYSQL,旧版默认=XCOM
# 各节点通讯端口不可随意使用:MYSQL必须用3306,XCOM可以用33061
# group_replication_communication_stack = MYSQL
# 事务写入算法方式(组复制默认的XXHASH64,<=8.0.1版本默认值为OFF)
#transaction_write_set_extraction = XXHASH64
# 设置群组白名单,包含在内的节点才能加入
#(旧版本CommunicationStack=XCOM时有效)
#loose-group_replication_ip_whitelist="192.168.1.0/24"
# 复制单位大小;默认 150000000 字节,可适当加大以提升复制效率
#loose-group_replication_transaction_size_limit = 1500000000
# 数据复制时,外键级联检测;本次测试不需要那么严谨,默认=OFF
#loose-group_replication_enforce_update_everywhere_checks = OFF
# 为创建 InnoDB Cluster,所要屏蔽的库表类型,默认值如下
#disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
以上 cnf 中绝大多数的配置项,在后续 shell 管理集群时,都会有对应的参数设置,以覆盖 cnf 原有配置 。
这里以[ 4.1 必须配置项 ]为模板,分别创建三个 cnf 配置文件: mc1.cnf 、 mc2.cnf 、 mc3.cnf .
后续容器启动时,分别对应各自节点的 cnf 文件。 各 cnf 唯一不同的配置项是 server_id .
这里假设三个SQL实例(集群至少),用 docker container 启动运行起来.
运行容器为集群必要的绑定项 :
以下唯一不同的是:hostname、ip、container-name、cnf 项.
# 第一个SQL容器的启动
docker run -dit \
--restart unless-stopped \ # 非人为宕机后自动重启
-e LANG=C.utf8 \ # 设定系统字符集
-e TZ=Asia/Shanghai \ # 设定系统时区
-e MYSQL_ROOT_PASSWORD=sa. \ # SQL实例 root 密码
--network br.mysql.clus \ # 使用的网路名称(自定义创建的网络)
--ip 12.12.0.1 \ # 指定 IP,集群模式建议固定 IP
--name mysql.clus.n1 \ # 容器名称
--hostname mc1 \ # 容器内计算机名称(用以集群内的节点通讯)
-v /etc/hosts:/etc/hosts \ # 统一 hosts 配置
-v /my/mc1.cnf:/etc/my.cnf \ # 各实例的配置文件
mysql:8.0.31
# 第二个SQL容器的启动
docker run -dit \
--restart unless-stopped \
-e LANG=C.utf8 -e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=sa. \
--network br.mysql.clus --ip 12.12.0.2 \
--name mysql.clus.n2 --hostname mc2 \
-v /etc/hosts:/etc/hosts \
-v /my/mc2.cnf:/etc/my.cnf \
mysql:8.0.31
# 第三个SQL容器的启动
docker run -dit \
--restart unless-stopped \
-e LANG=C.utf8 -e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=sa. \
--network br.mysql.clus --ip 12.12.0.3 \
--name mysql.clus.n3 --hostname mc3 \
-v /etc/hosts:/etc/hosts \
-v /my/mc3.cnf:/etc/my.cnf \
mysql:8.0.31
记住以上三个容器的SQL镜像提供的环境变量 MYSQL_ROOT_PASSWORD,也就是给 SQL Instance 的 root 设置密码为 sa.;在后续的过程当中,都以 root 及这样的密码作为凭证.
集群三个节点容器运行效果,这里把各自节点容器名称分别为: mysql.clus.n1 mysql.clus.n2 mysql.clus.n3 。
作为集群节点的管理工具,安装在任意(Win/Linux)网络互通的系统都可以,这里用官网提供的 [MySQL Yum Repository] 的方式安装到 Linux VM 。
可参考官网: https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ 。
# MySQL Yum Repository 安装到 Linux 系统中
dnf install https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm -y
dnf clean all && dnf makecache
# 在 Repository 中搜索以 mysql-shell 为前缀的应用
dnf list mysql-shell*
# 安装特定版本的 mysql-shell
dnf install -y mysql-shell-8.0.31
这里已经安装过,截图仅是搜索并安装的示例:
安装完成后,进入 mysql-shell 命令行请输入: mysqlsh 。
mysql-shell 提供了三种命令模式: JavaScript / python / sql ;默认为 js 模式.
这里说明一下接下来常用到的 mysqlsh 命令:
全局对象 | 说明 |
---|---|
dba | 用于集群的管理 |
mysql | SQL服务连接对象 |
shell | 通用函数 |
os | 与系统有关的操作 |
util | 工具函数 |
shell 通用命令 | 说明 |
\? ; \help | 获得帮助 |
\js ; \py ; \sql | 切换模式 |
\ | 多行命令 |
\c ; \connect { user }:{ host }:{ port } | 连接到目标实例 |
\disconnect | 断开连接会话 |
\reconnect | 重新连接到会话 |
\! ; \system | 执行系统脚本 |
\q ; \quit ; \exit | 退出当前会话(mysql-shell) |
在接下来的过程当中,经常会用 :
\js 方式组建管理 MySQL 集群 \sql 方式查询目标实例的数据信息 。
在 mysqlsh 中,使用 MySQL AdminAPI 提供的 dba 对象及函数来 检测节点/创建集群/配置集群/解散集群/重启集群 等的集群管理操作.
有关于 AdminAPI 的研究,可参考官方文档: https://dev.mysql.com/doc/mysql-shell/8.0/en/admin-api-userguide.html 。
接下来以 dba 对象为主的集群管理操作.
前期,已经运行了三个MySQL容器,参考[ 5.2 docker 启动多个SQL实例容器 ],并且配置了运行集群的必要参数;但在创建集群前,通常都会检验目标实例是否符合加入集群的要求:
先连接任意一个 Instance,比如: \c root@mc1:3306 (还记得 root 密码么,也许会让你输入凭证) 。
然后检测所有节点的配置,是否符合集群的基本运行条件 (各 cnf 的必须配置项,未配好的会提醒) :
# 分别检测各节点(还记得先前配置的 hosts 各名称么)
dba.checkInstanceConfiguration('root@mc1:3306');
dba.checkInstanceConfiguration('root@mc2:3306');
dba.checkInstanceConfiguration('root@mc3:3306');
过程如下截图示例:
如果检测失败 。
1、可用 \c 方式连接到目标实例后 2、再用 dba.configureLocalInstance(); 方法引导完成必须的配置 。
# 在任意目标实例中,创建名为 clus-1 的集群
# 那么,当前实例会被作为 Master 角色存在
var clus = dba.createCluster('clus-1');
# 或者,也可以指定目标实例名称,创建集群
# 如:dba.createCluster('clus-1',{localAddress:'root@mc2:3306'});
# 还记得名为 group_replication_local_address 的配置参数么,所以以上 localAddress 的值会覆盖此参数值
#
# 集群创建完成后,可用 status(); 函数查看当前集群状态信息
clus.status();
#
# 也可以获取当前节点所处的集群
var clus1 = dba.getCluster();
从上图可以看出:此节点为集群的主节点、可读可写、单主多从模式、集群内部通讯地址为 mc1:3306.
加入节点,需要设定数据恢复 (与主节点保持一致) 的方式:克隆、增量、自动.
可以加参数指明方式;也可以在新增过程中按系统提示选择.
# 加入新的集群节点,过程中通常选择 Clone 模式来复制主节点的数据
clus.addInstance('root@mc2:3306');
clus.addInstance('root@mc3:3306');
# 当然也有提醒信息;
# 比如:clus.addInstance('root@mc2:3306',{localAddress:'root@mc2:3306'});
# 追加的 localAddress 参数,更明确的指出此节点对集群的通讯地址
# 所以也可省略的参数,mysqlsh 也可自动取实例 Uri 作为 localAddress 参数值
#
# 此时再 .status() 查看集群状态
clus.status();
集群添加新节点图例:
集群 .status() 状态信息图例:
... ... 加入更多的节点; 单主多从的集群创建完成.
节点自动连接到集群 。
当因为连接超时或性能压力等,被自动踢出集群的节点,恢复后自动连接到集群; 或人为修复故障后,可以手动通过 rejoinInstance() 函数再次连接到集群中; 被 removeInstance() 的节点恢复正常后,通过 addInstance() 再次加入集群.
全局函数 | 说明 |
---|---|
dba.configureLocalInstance(); |
配置当前节点为符合集群的要求,不符合的配置项会自动提示。 |
dba.checkInstanceState({Uri}); |
检查节点配置,列出节点的当前具体情况(冲突/分歧/错误)。 |
dba.configureInstance({Uri}, { option:value }); |
配置远程SQL实例节点参数。 |
dba.checkInstanceConfiguration({Uri}); |
检查指定节点是否符合加入集群的要求。 |
dba.createCluster({cluster-name}); |
以指定(默认:当前)节点上下文为基准,创建一个集群。 |
dba.getCluster({cluster-name}); |
取得当前节点所处/参数指定的集群对象。 |
dba.rebootClusterFromCompleteOutage({cluster-name}); |
重启指定的集群(建议先 check 各节点) |
dba.dropMetadataSchema(); |
删除整个 Schema(无法恢复)。 |
当前集群对象函数 | 说明 |
{cluster}.addInstance({Uri}); |
集群加入新节点。 |
{cluster}.status(); |
集群状态信息。 |
{cluster}.describe(); |
集群结构信息。 |
{cluster}.removeInstance({Uri}); |
集群内移除指定的节点实例。 |
{cluster}.rescan(); |
(属于集群)列出未运行在集群内的节点实例。 |
{cluster}.rejoinInstance({Uri}); |
(故障节点修复后)重新连接到集群。 |
{cluster}.foreQuorumUsingPartitionOf({Uri}); |
恢复集群(建议先 check 各节点) |
{cluster}.dissolve(); |
解散集群(各节点数据保持现状)。 |
{cluster}.help({fun-name}); |
帮助;所有函数 或 指定函数。 |
{cluster}.options(); |
列出此集群可配参数。 |
{cluster}.setOption({option}, {value}); |
为此集群设定配置项。 |
{cluster}.setInstanceOption({Uri}, { option:value }); |
为此集群的指定节点实例,设定配置项。 |
{cluster}.listRouters(); |
查看路由信息 |
{cluster}.setupAdminAccount({account-name}); |
为集群中的所有节点统一创建相同的账户高权限及密码(替代root)。 |
{cluster}.setupRouterAccount({account-name}); |
为集群中的路由统一创建相同的账户高权限及密码(替代root)。 |
函数应用场景案例: 重启集群 。
可能预先要做的准备工作:在集群中寻找数据集更接近完善的节点,以作为 Master 节点.
dba.rebootClusterFromCompleteOutage({ dryRun : true });
show variables like '%gtid_executed%';
参数应用场景案例: 节点异常时踢出集群前的延迟时长 。
当某个节点异常时,系统会有5秒的检测时长,之后还会有延迟时长,后踢出集群;为了防止被误踢,延迟时长可配.
{cluster}.addInstance({Uri},{ expelTimeout : 8 });
{cluster}.setInstanceOption({Uri},{expelTimeout:8});
那,,,mysql-shell 管理的集群有哪些参数可以设定的呢?
{cluster}.options(); 函数列出每个节点的所有可设置参数: (截取部分) 。
有没有熟悉的参数。。.
这里 options 所有的参数都与 cnf 配置文件参数一一对应; 。
比如:可以用 dba.createCluster('{Uri}',{ key:value, key:value ... }); 这样的方式附带参数 。
比如:可以用 .addInstance('{Uri}',{ key:value, key:value ... }); 这样的方式附带参数 。
也可以用函数 .setOption( option, value ); 这样的方式完成参数设定.
用 mysql-shell 管理集群时,默认情况下,以上都可覆盖原有 (my.cnf) 配置,并可持久化 (my-auto.cnf) 保存.
测试场景 :在 Master 节点创建库/表/数据后;查看 Slave 节点 是否已同步 数据.
# 在 Master 节点创建库/表/数据
\c root@mc1:3306
create database clusterdb;
create table clusterdb.emp(id bigint not null AUTO_INCREMENT,usercode VARCHAR(32) DEFAULT NULL,createtime datetime default now(),PRIMARY KEY (id));
insert into clusterdb.emp(usercode) values ('Sol'),('wang');
# 查看 Slave 节点是否已同步数据
\c root@mc2:3306
select * from clusterdb.emp;
测试结果图 :主从数据 同步完成 .
测试场景 :Master 节点制造宕机(停机),集群选举出新的 Master 节点, 是否完成故障转移 .
1、假设的 Master 宕机: docker stop mysql.clus.n1 2、再查看集群 Master 角色所处节点.
# 连接到集群节点
mysqlsh --uri root@mc2:3306
# 查看集群节点状况
dba.getCluster().status();
测试结果上图 :其中 mc2:3306 节点已接替 Master 角色, 完成故障转移 .
docker mysql-router 镜像,官网有测试版,参考: https://hub.docker.com/r/mysql/mysql-router 。
既然非生产环境的稳定版,这里在容器中安装 mysql-router.
运行已有的 oraclelinux 镜像,并进入容器:
# oraclelinux 镜像运行出新容器
docker run -dit --restart unless-stopped -e LANG=C.utf8 -e TZ=Asia/Shanghai \
--name mysql.clus.mr --hostname mr \
--network br.mysql.clus --ip 12.12.0.5 \
-p 6446:6446 -p 6447:6447 \
-v /etc/hosts:/etc/hosts \
oraclelinux:9-slim
# 进入容器
docker exec -it mysql.clus.mr bash
容器内安装 mysql-router 。
通常:docker 镜像的系统,只提供最基本的应用功能,最大程度的简化,是 docker image 的特点之一。 所以:以下镜像的容器内,yum/dnf 已被移除,rpm 也被简化,但仅提供了最简陋的应用安装方式 microdnf。 当然:也可以通过 microdnf 来安装上功能强大的 yum/dnf 等,以下继续使用 microdnf 方式安装应用.
# 这里使用官方提供的 Yum Repository 方式安装
curl -#O https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm
rpm -ivh mysql80-community-release-el9-1.noarch.rpm
# 作为镜像的微型系统,当然是仅提供基本功能
# yum/dnf 都没了,当然也可以安装上,这里使用自带的 microdnf 命令安装
# 更新 Repos,为了后续更快的应用安装(多等会)
microdnf clean all && microdnf makecache
# 模糊搜索以 mysql-router 为前缀的安装包
microdnf repoquery mysql-router*
# 搜索到的包,安装指定版本;格式:{name}-{版本号}
microdnf install mysql-router-community-8.0.31 -y
# 查看安装效果
mysqlrouter -V
# 命令有多种可选参数,这里用以下方式初始化 mysql-router 实例
# 集群 Master主机的URI格式:{sql-user}:{pass}@{host}:{port}
mysqlrouter --bootstrap root:sa.@mc1:3306 --user=root --force
# 初始化后产生的配置文件可查看,或修改配置项
cat /etc/mysqlrouter/mysqlrouter.conf
# 启动后台运行实例
mysqlrouter --user=root &
a、创建空文件夹,作为制作镜像的根目录; 。
b、文件夹中创建 Dockerfile 文件: touch Dockerfile ; 。
Dockerfile 文件内容如下:
# 基于 Oracle 9 Linux 系统的依赖
FROM oraclelinux:9-slim
# 系统默认字符集
ENV LANG C.utf8
# 系统默认时区
ENV TZ Asia/Shanghai
# mysql-router 用到的集群 Master Uri 作为系统变量
# 集群 Master Uri 格式为:{user}:{pass}@{host}:{port}
ENV MASTER_URI root:sa.@mc1:3306
# 以下运行在指定账户下
USER root
# 进入系统后的默认目录
WORKDIR ~
# 制作系统所需的命令步骤
# - 网络安装MySQL官网提供的 Yum Repository,编译 mysql-router 在此 Repo 下安装
RUN rpm -ivh https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm
RUN microdnf clean all
RUN microdnf makecache
RUN microdnf install mysql-router-community-8.0.31 -y
RUN mysqlrouter --bootstrap $MASTER_URI -u=root --force
# 对外提供 mysql-router 的读写端口
EXPOSE 6446 6447
# mysql-router 初始化 并 启动
ENTRYPOINT mysqlrouter -u=root
c、Dockerfile 文件保存退出后,在此目录下执行 build 命令,生成 image 包.
# build 格式:docker build -t {image-name}:{tag} {根目录}
docker build -t mysql/router8:1.0 .
# 查看 image list
docker image ls
将制作的 mysql/router8 镜像运行到容器 。
docker run -dit \
--restart unless-stopped \ # 非手动关机时自动重启
--name mysql.clus.mr \ # 容器名称
--hostname mr \ # 计算机名
--network br.mysql.clus \ # 指定网络
--ip 12.12.0.5 \ # 集群时建议使用固定IP
-p 6446:6446 -p 6447:6447 \ # 对外开发的端口映射
-v /my/mr.hosts:/etc/hosts \ # 集群时的 hosts 优化
-e MASTER_URI=root:sa.@mc2:3306 \ # 集群 Master uri 地址
mysql/router8:1.0 # 使用制作的镜像
实例节点 + 路由 的容器列表:
集群查看路由信息: listRouters() 。
所以,,,客户端在连接的时候,不同的动作连接对应的端口号.
首先,客户端 mysql-cli 先连接到 mysql-router; 。
mysql-router 按集群状况,把读写动作连接到不同的集群节点上.
测试办法 :客户端 mysql-cli 连接 mysql-router 的写入端口 6446, 是否连接到 Master?
# mysql-cli 连接到 mysql-router
mysql -h mr -u root -P 6446 -p
# - 验证连接的主机(是不是 mc1)
select @@hostname, @@port;
上图测试结果显示 :路由的 6446 端口连接到 Master,并可写入数据; 测试通过 .
测试办法 :客户端 mysql-cli 连接 mysql-router 的只读端口 6447, 是否连接到 Slave?
# mysql-cli 连接到 mysql-router
mysql -h mr -u router_newuser_1 -P 6447 -p
# - 验证连接的主机(是不是 mc2,mc3)
select @@hostname, @@port;
# - 验证数据是否已经同步到从机
select * from emp;
上图测试结果显示 :路由的 6447 端口,连接到了 Slave 节点,并可查询数据; 测试通过 .
测试场景 :透过路由 6447 只读端口,多次连接查询数据,是否轮询连接到不同的只读节点?
上图测试结果显示 :多次连接只读端口,连接到了不同的只读节点; 测试通过 .
最后此篇关于MySQL8.0高可用集群化·mysql-shell·mysql-router·docker·单主多从的文章就讲到这里了,如果你想了解更多关于MySQL8.0高可用集群化·mysql-shell·mysql-router·docker·单主多从的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在寻找一种方法来创建根据价格选择我的产品的过滤器(选择下拉菜单)。 我知道这样的查询是完全可能的: SELECT * FROM products ORDER BY price ASC SELECT
函数参数中或显示尺寸时(高度,宽度)的顺序是否有约定? 最佳答案 我不知道大量的语言,但我使用过的语言(宽度,高度)。它更适合沿着 (x, y) 坐标线。 关于language-agnostic -
在我的表单中,我让用户输入房间的长度高度和宽度以获得 m2、m3 和瓦特的计算值。但是用户也应该能够直接输入 height 和 m2 来获取值。我尝试了很多语法,但 if else 不能正常工作。我知
我在 Elasticsearch 中创建了一个索引,看起来像 {"amazingdocs":{"aliases":{},"mappings":{"properties":{"Adj Close":{"
我有以下功能,我需要清除数据库中的所有图片列并移动到文件系统。当我一次性完成这一切时,内存太多并且会崩溃。我切换到递归函数并执行 20 次写入和批量操作。 我需要为大约 6 个表执行此操作。我的 Re
我正在编写一个函数来计算 PI 的值,并将其作为 double 值返回。到目前为止,一切都很好。但是一旦函数到达小数点后14位,它就不能再保存了。我假设这是因为 double 有限。我应该怎么做才能继
2020年是中国CDN行业从98年诞生到今天快速发展的第二十四年,相关数据显示,全国感知网速持续上扬,达到了3.29兆/秒,标志着在宽带中国的政策指导下,中国的网速水平正在大步赶上世界发达国家的水平
在 aerospike 集合中,我们有四个 bin userId、adId、timestamp、eventype,主键是 userId:timestamp。在 userId 上创建二级索引以获取特定用
$('#container').highcharts('Map', { title : { text : 'Highmaps basic demo'
有没有办法显示自定义宽度/高度的YouTube视频? 最佳答案 在YouTube网站上的this link中: You can resize the player by editing the obj
我使用 Highcharts ,我想在 Highcharts 状态下悬停时制作动态不同的颜色。 正如你可以看到不同的颜色,这就是我做的 var usMapChart , data = [] ; va
在所有节点上运行 tpstats 后。我看到很多节点都有大量的 ALL TIME BLOCKED NTR。我们有一个 4 节点集群,NTR ALL TIME BLOCKED 的值为: 节点 1:239
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我已经 seen >2 字节的 unicode 代码点,如 U+10000 可以成对编写,如 \uD800\uDC00。它们似乎以半字节 d 开头,但我只注意到了这一点。 这个 split Actio
有人可以帮我理解为什么我的饼图百分比计算不正确吗?看截图: 根据我的计算,如 RHS 上所示,支出百分比应为 24.73%。传递给 Highcharts 的值如下:- 花费:204827099.36-
我阅读了有关该问题的所有答案,但我还没有找到任何解决方案。 我有一个应用程序,由我的 api 服务器提供。 Wildfly 8.1 和 Mysql 5.6。当查看时间到来时(Wildfly 服务器连接
我正在用选定的项目创建圆形导航。当用户单击任何项目时,它将移动到定义的特定点。一切都很好,除了当你继续点击项目时,当动画表现不同并且项目在 360 度圆中移动并且它被重置直到你重复场景时,我希望它
我是一名优秀的程序员,十分优秀!