MySQL
集群搭建测试的研究中
对于业界主流方案自然不能跳过
在此,整理成完整的文章,希望道友能得到参考价值 …
【注】:Percona XtraDB Cluster(简称 PXC 集群)
—— 业界主流的MySQL
集群方案
PXC
是基于 Galera
协议的高可用集群方案
可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据强一致性
PXC
最大的优势:强一致性、无同步延迟 (牺牲性能) 介绍不做赘述,可参考 ——【MySQL 高可用方案-PXC 环境部署记录】
CentOS版本: CentOS Linux release 7.9.2009 (Core)
MySQL 版本: 5.7.32
PXC 版本 : percona/percona-xtradb-cluster 最新
前期准备
Vmware
虚拟机在此,我以三台创建运行的
CentOS7
作为宿主机,进行配置操作演示
虚拟机 ip | 端口 | 容器 | 数据卷 | 角色 |
---|---|---|---|---|
192.168.80.221 | 9001 | pn1 | pnv1 | Docker Swarm 管理节点,Master 节点 |
192.168.80.222 | 9001 | pn2 | pnv2 | worker 节点 |
192.168.80.223 | 9001 | pn3 | pnv3 | worker 节点 |
3306: # mysql 实例端口
4567: # PXC cluster 相互通讯的端口
4444: # 用于 SST(State Snapshot Transfer): 全量传输
4568: # 用于 IST(Incremental state Transfer):增量传输传送
SELINUX
、将 MySQL 数据库服务停止安全增强型
Linux(Security-Enhanced Linux)SELinux
主要由美国国家安全局开发
【荐】
,永久关闭 Selinux:
"vi /etc/selinux/config"
把 "SELINUX"
属性值设置成 disabled
,然后 reboot
重启"setenforce 0"
[root@localhost ~]# yum -y install ntp ntpdate
[root@localhost ~]# ntpdate 0.asia.pool.ntp.org
[root@localhost ~]# hwclock --systohc
[root@localhost ~]# date
2021年 01月 08日 星期五 09:54:23 CST
Docker Swarm
集群为了使三台服务器进行连接,如果没有安装
"docker"
,需要先执行命令:yum install -y docker
【拓展】:
docker -v
判断 docker 是否安装成功:docker
docker 的启动/关闭/重启:service docker start
、service docker stop
、service docker restart
service docker restart
)
2377
:用于集群管理通信的TCP端口
4789
:用于容器覆盖网络
7946
:用于容器网络发现
firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=4789/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --zone=public --add-port=7946/tcp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent
firewall-cmd --reload
注意,以上的操作,要对三台虚拟机,全部进行配置哦!!!
选择一台服务器作为管理集群的服务器,此处,我选择的是【192.168.80.221】
docker swarm init
则会得到一个形如下面的管理者口令[root@localhost /]# docker swarm init
Swarm initialized: current node (g706owlgszx493xhpsb44k9t0) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-4ea65xsm8xsyhrmn42qg125b10dxtcmt80gnuijnnskddces2n-6fok68mg86nf5lkah1wnnj6ra \
192.168.80.221:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
192.168.80.222
、192.168.80.223
)
在 docker
服务启动的前提下
都要执行上面的口令swarm
集群的所有节点
只能在管理主机下【192.168.80.221】
才能查看docker node ls
【拓展】:
docker node rm -f [节点的ID]
如果要解散 swarm 集群
先再 【manager 节点】上删除 所有 【worker 节点】
再强制删除自己,执行:docker swarm leave -f
最后,还需要在各个 【worker 节点】主机上执行:docker swarm leave
swarm_mysql
docker network create -d overlay --attachable swarm_mysql
【拓展】:
docker network inspect swarm_mysql
所有虚拟网络: docker network ls
删除虚拟网络: docker network rm swarm_mysql
搭建 PXC 集群
Docker 仓库中的 PXC官方镜像:
https://hub.docker.com/r/percona/percona-xtradb-cluster
docker pull percona/percona-xtradb-cluster
建议配置一下加速镜像,请参考
【附录 - a: 配置 docker 加速镜像】
docker tag percona/percona-xtradb-cluster pxc
docker rmi percona/percona-xtradb-cluster
此时,可以通过命令查看所有的镜像:
docker images
注意:
第一个启动的 PXC节点是【主节点】,它要初始化 PXC 集群
PXC 启动之后,就没有【主节点】的角色了!此处只是随机选择了【192.168.80.221】
,其实任意一个都可以! 鄙人设置的是以"9001"
端口访问 集群,所以记得开启端口(也可以选用3306
等任意不冲突的端口!)
【192.168.80.221】
注意:在这一步之前,要把 MySQL 数据库停止服务 !
[root@localhost ~]# service mysqld status
ERROR! MySQL is not running
【附录 - b). 创建节点参数解释】
docker run -d --name=pn1 --net=swarm_mysql -p 9001:3306 -v pnv1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 pxc
【补充知识点】:
此处有必要提及一下,注意命令中的参数 "-v pnv1:/var/lib/mysql"
即:数据挂载在名称为 "pnv1"
的数据卷上,对应于宿主机的 "/var/lib/mysql"
路径
通过命令:docker inspect pnv1
可以找到数据卷位置,后期作为主节点的启动,是要知道这个路径的!MySQL
服务启动了!】此时,可以查看虚拟网络 :
docker network inspect swarm_mysql
,会发现,主节点ip
成功配置进去了:
【提示】:
MySQL
服务启动失败,建议先将容器停止,不然 MySQL
服务各种报错
对节点的其他操作,请阅读 【附录 - c). 节点操作指令】
Navicat
等数据库连接工具测试是否能够连接 【提示】:
- `通过我多次的配置测试发现,【主节点】配置基本不会有多少问题`
必须主节点可以访问了,才能创建从节点,否则会闪退!
【192.168.80.222】
相信,会有很多人在创建第二个节点时就会遇到问题,注意提示,要进行日志的排查:
docker logs [节点名]
docker run -d --name=pn2 --net=swarm_mysql -p 9001:3306 -v pnv2:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=pn1 pxc
注意:
"-e CLUSTER_JOIN"
参数,表示与【主节点】容器同步
此处的命令,与创建【主节点】不同的地方,也只有参数 --name(节点名)
、-v(数据卷)
,其他酌情自定义docker ps -a
Navicat
测试是否能够连接也可以查看虚拟网络情况,通过命令:
docker network inspect swarm_mysql
【192.168.80.223 】
docker run -d --name=pn3 --net=swarm_mysql -p 9001:3306 -v pnv3:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=pn1 pxc
docker ps -a
其他操作,不做赘述!如果有更多的从节点需要创建,可以举一反三 …
推荐的方式,需要进入
【主节点】
的 mysql,运行查询语句:show status like 'wsrep%';
[192.168.80.221]
的查询结果如下:
可以看到 "wsrep_incoming_addresses"
的值就是我们三个容器的IP地址
对于其他参数解释,建议可以参考 —— 【MySQL Galera cluster集群常用参数说明】
另外,我发现,在节点顺利启动后,可以通过查看虚拟网络信息,确认挂载情况
docker network inspect swarm_mysql
[root@localhost ~]# docker network inspect swarm_mysql
[
{
"Name": "swarm_mysql",
"Id": "ir06z2hjlfduliphte8chwrop",
"Created": "2021-01-14T15:46:33.522125189+08:00",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Containers": {
"4d09f2b49a771f0976ea6379d1585059b1f54041ccdf975d540fc9e319258d3f": {
"Name": "pn1",
"EndpointID": "27662762e11842e96125cdca03a66941c7fe4c2574eea6a7cd29ed8a4b8cfea0",
"MacAddress": "02:42:0a:00:00:02",
"IPv4Address": "10.0.0.2/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": {},
"Peers": [
{
"Name": "localhost.localdomain-bedc99cf44f1",
"IP": "192.168.80.221"
},
{
"Name": "localhost.localdomain-986f2f07e8b7",
"IP": "192.168.80.222"
},
{
"Name": "localhost.localdomain-4a1e3925814d",
"IP": "192.168.80.223"
}
]
}
]
集群同步验证
验证是极为简单的,直接在任意节点数据库连接上,创建 db、创建数据表、操作数据
【题外话】:
MySQL
数据库主从同步没啥大的区别
只是没有了主从之分
那就相当于所有节点【互为主备】
对比参考 —— 【CentOS7 下 MySQL5.7.32 主从复制+同步配置操作 (一主多从+多主多从)】
PXC 节点宕机以及重启操作
此处,推荐参考 ——
【MySQL 之 PXC 集群搭建:宕机操作】
知识点
PXC
在退出的时候会给集群中最后退出的那台打上标记,
当集群重新启动的时候
需要尽量先启动最后关闭的那台节点机器
并且要按照主节点方式启动!即,以
指定主节点
形式进入PXC
集群创建的容器(理解起来即为【从节点】如:pn2、pn3)如果主节点没有完全启动成功,从节点就会闪退
直接运行指令:
docker restart [节点名]
,数据会自行同步
此时,有两种可选择的方案
docker restart [节点名]
如果发现启动后闪退
建议确认下数据卷中 "grastate.dat"
文件的 safe_to_bootstrap
参数为 0
再以 指定主节点方式 启动"grastate.dat"
文件的 safe_to_bootstrap
参数为 1
再以 主节点方式 启动即,以
自身为主节点
启动的容器(理解起来即为【主节点】,如 : pn1)
如果能确定,原来作为【主节点】的是最后一个离开集群的,可直接运行:docker restart [节点名]
"grastate.dat"
文件的 safe_to_bootstrap
参数为 1
然后,执行启动命令:docker start [节点名]
或者 docker restart [节点名]
等待查看第一个节点成功启动后,
再按顺序,依次启动其他从节点:docker restart [节点名]
此时,要考虑使用指定主节点方式进行启动
docker stop [节点名]
、docker rm [节点名]
原来的数据卷无需删(继续使用,避免数据丢失)
然后,确认一下:数据卷中 "grastate.dat"
文件的 safe_to_bootstrap
参数为 0
接着,再以从节点方式创建容器,加入集群(注意参数 "-e CLUSTER_JOIN"
的指定)stop
, rm
操作
再从创建节点步骤开始,执行一遍!我在退出虚拟机时,习惯先关掉 从机
docker inspect [数据卷名]
然后,修改其目录下的 "gratate.dat"
文件中的 safe_to_bootstrap
参数为 1
接着执行命令:docker restart pn1
docker restart pn2
docker restart pn3
至此,三个
PXC
节点都已启动,且数据同步
PXC 集群实际应用探讨
ThinkPHP5
上的使用以鄙人常用的
ThinkPHP5
框架使用为例
那么,在 中的配置参考如下:
MyCat
部署读写分离【提示】:
“Replication”
集群部署通常来讲,对于数据库集群部署,**
"PXC"
** 都会拿来与"Replication"
进行对比!
此处,引用前辈文章,以作知识共享咯 ——
【Docker 部署 Mysql 集群】
【Replication
部署方案】:
【PXC
部署方案】:
注意,两种方案不是对立的,一个大型项目中,完全可以根据自己的业务 :
结合使用、取长补短
**!**
报错排查及解决
这只是我遇到的几个关键问题,酌情参考 …
“transport: x509: certificate has expired or is not yet valid”
[root@localhost ~]# yum -y install ntp ntpdate
[root@localhost ~]# ntpdate 0.asia.pool.ntp.org
[root@localhost ~]# hwclock --systohc
[root@localhost ~]# date
2021年 01月 08日 星期五 09:54:23 CST
“error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding”
当发现,节点无法连接后,这时就要查看日志
2021-01-14T09:02:35.487308Z 0 [ERROR] [MY-000000] [Galera] handshake with remote endpoint ssl://10.0.0.2:4567 failed: asio.ssl:67567754: 'invalid padding' ( 67567754: 'error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding')
This error is often caused by SSL issues. For more information, please see:
https://per.co.na/pxc/encrypt_cluster_traffic
--------
"ERROR"
信息的阅读
建议阅读文章链接:https://per.co.na/pxc/encrypt_cluster_traffic
于是在官方文档中注意到一个提示信息: 重启节点,也可使用命令:
docker restart [节点名称]
附录
docker
加速镜像
Docker
从Docker Hub
拉取镜像,因为是从国外获取,所以速度较慢
daemon.json
vi /etc/docker/daemon.json
{
"registry-mirrors": ["http://hub-mirror.c.163.com","https://mirror.ccs.tencentyun.com","https://ung2thfc.mirror.aliyuncs.com"]
}
# 重新加载某个服务的配置文件
systemctl daemon-reload
# 重新启动 docker
service docker restart
【Docker run 命令】
命令 | 说明 |
---|---|
-d | 代表创建的容器在后台运行 |
–name=pn1 | 容器名称,自定义 |
–net=swarm_mysql | 加入到 swarm_mysql的虚拟网络 |
-p 9000:3306 | 端口映射 宿主机端口:容器端口 |
-v pnv1:/var/lib/mysql | 数据卷挂载在 "pnv1" 数据卷 可以理解为虚拟的磁盘,容器在保存数据的时候往 "/var/lib/mysql" 路径保存数据,其实就是把数据包存在数据卷上了如果在这之前没有数据卷 pnv1,会自动创建一个进行挂载 |
–privileged | 表示有读写权限 |
-e MYSQL_ROOT_PASSWORD=mT123456 | Mysql 的 root 密码 (跟原来数据库设定的 root 密码没关系) |
-e CLUSTER_NAME=PXC1 | PXC 集群名称 (注意不要命为关键词:"PXC") |
-e XTRABACKUP_PASSWORD=mT123456 | PXC 集群之间数据同步的密码 |
-e CLUSTER_JOIN=pn1 | 表示与 pn1节点同步 (第一个节点是没有该参数的!) |
pxc | 来自哪个镜像创建 |
感觉,用的还挺频繁的,比如节点配置错误,想换名字,删除数据卷时都会用到!
用途 | 指令 |
---|---|
停止节点 | docker stop 节点名 |
重启节点 | docker restart 节点名 |
查看所有节点 | docker ps |
删除节点 | docker rm 节点名 |
查看日志 | docker logs 节点名(建议用来排查错误) |
注:PXC 容器只支持数据卷挂载方式,不支持目录挂载
docker inspect [数据卷名]
[root@localhost download]# docker inspect pnv1
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/pnv1/_data", # 这里是在宿主机的保存位置
"Name": "mTv1",
"Options": {},
"Scope": "local"
}
]
文章