大家好,我是小盒子。上次推文:MySQL篇(三)MySQL数据增量迁移方案。通过实践详细阐述了MySQL零停机在线迁移数据。
今天的主题:MySQL篇(四):玩转MySQL高可用,快速搭建Percona XtraDB Cluster(PXC)集群方案。。
一、前言
在MySQL篇(一)的时候我们提了在MySQL在二十多年的发展过程中,各种高可用集群方案百花齐放,就像天上的繁星,让我们这些互联网从业者眼花缭乱。但是,相比于其他的集群方案,Percona XtraDB Cluster(PXC)更像是星辰中的北极星,方向明确,坚如磐石。
话说PXC就像是一位业界大佬,在各种高可用集群方案的大海中闪耀着自己的光芒。通过多个MySQL节点之间的复制实现数据同步和备份,极大地提高了系统的可用性和可靠性,让我们的数据库系统像纯种泰迪一样,可爱又稳定。
在这个不确定和瞬息万变的互联网时代,我们需要一个坚实可靠的数据库集群解决方案,就像一位保护神一样,保卫我们的数据安全。PXC集群解决方案就是这样一位保护神,他能够自动检测并解决故障,让我们的系统跑得更快,更稳定,更安全。
所以,如果你还在为MySQL高可用集群方案的选择而犯愁,那么就来试试PXC吧!相信它会成为你的贴心小棉袄,让你的MySQL数据库系统变得更加强大可靠,好像一位吐槽鬼说的那样,“一旦选择了PXC,你就不会再想离开它了”。
二、环境说明
1.1 环境要求
1.2 环境搭建
- 1、准备一台centos7虚机
- 2、安装docker
yum install docker-ce-20.10.8 systemctl daemon-reload systemctl enable docker && sudo systemctl start docker
- 3、安装docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose –version
三、MySQL-PXC集群方案
3.1 MySQL集群方案介绍
MySQL-pxc集群是指一个基于MySQL数据库的高可用集群解决方案,PXC全称Percona XtraDB Cluster,是Percona公司为解决MySQL集群高可用性、扩展性、负载均衡等问题推出的一种分布式数据库解决方案。PXC利用多个MySQL服务器节点之间的复制来实现数据的同步和备份,同时可以连接到所有节点进行读写操作。
PXC是一个基于Galera Replication插件的集群解决方案,Galera Replication插件是一种基于磁盘级别的多主复制技术,支持广播式复制和多线程串行复制,可以提供高可用性、高性能和最终一致性的解决方案。
MySQL-pxc集群可以提供高可用性和扩展性,保证了数据库的高可用性和数据的完整性。在一个MySQL节点的故障情况下,其他节点可以接管服务,确保系统的可用性和可靠性。同时,MySQL-pxc集群可以进行水平扩展,在增加节点的情况下提高了系统的性能和负载均衡能力。
除此之外,MySQL-pxc集群还提供了快速故障检测和自动数据修复功能,可以在出现故障时自动恢复服务。同时,MySQL-pxc集群也支持高级数据保护功能,确保数据的机密性和完整性。
对于单节点数据库而言,主要存在以下弊病:
- 单点故障问题:一旦这个节点出现故障,整个数据库就会挂掉,导致服务无法使用。
- 读写性能瓶颈:随着数据量的增加,单节点数据库的读写性能会受到限制,无法满足高并发访问需求。
- 数据备份问题:单节点数据库没有数据备份和恢复机制,一旦数据丢失,很难恢复。
我们通过图示来对比一下常见的Repliaction集群和PXC集群:
PXC集群方案:
“很明显 PXC方案在任何一个节点写入的数据都会同步到其他节点,数据双向同步的(在任何节点上都可以同时读写)。
”
Replication 集群方案:
“Replication方案只能在Master数据库进行写操作,在Slave数据库进行读操作。如果在Slave数据库中写入数据,Master数据库是不能知道的(单向同步的)。
”
PXC 数据的强一致性:
- PXC 采用同步复制,事务在所有集群节点要么同时提交,要么不提交。
- Replication 采用异步复制,无法保证数据的一致性。
PXC写入操作:
“当一个写入请求到达PXC集群中的一个 mysql(node1数据库) 数据库时,node1数据库会将该写入请求同步给集群中的其他所有数据库,等待所有数据库都成功提交事务后,node1节点才会将写入成功的结果告诉给 node1的客户端。PXC 的强一致性对保存高价值数据时特别重要。
”
Replication集群写入操作:
“当一个写入请求到达 Master数据库时,Master数据库执行写入操作,然后 Master 向客户端返回写入成功,同时异步的复制写入操作给 Slave数据库,如果异步复制时出现问题,从数据库将无法执行写入操作,而客户端得到的是写入成功。这也是弱一致性的体现。
”
四、MySQL-PXC集群搭建
4.1 PXC集群安装
1.镜像拉取
Docker的镜像仓库中包含了PXC数据库的镜像,地址:https://hub.docker.com/r/percona/percona-xtradb-cluster
“拉取最新版本:docker pull percona/percona-xtradb-cluster 指定版本下载:docker pull percona/percona-xtradb-cluster:8.0.23
”
2.自定义网络
docker network create --driver bridge --subnet 10.139.0.0/16 --gateway 10.139.0.1 pknet
“预先创建一个自定义的网络pkulaw_net,此处的10.139可以自定义,不冲突即可。创建自定义网络的好处是不同的集群使用不同的网络,保证集群是安全和健康的。
”
自定义网络相关命令:
docker network connect -- Connect a container to a network create -- Creates a new network with a name specified by the disconnect -- Disconnects a container from a network inspect -- Displays detailed information on a network ls -- Lists all the networks created by the user prune -- Remove all unused networks rm -- Deletes one or more networks
网络模式:
bridge :桥接 docker(默认,自己创建也是用bridge模式) none :不配置网络,一般不用 host :和所主机共享网络 container :容器网络连通(用得少!局限很大)
#查看网络的相关信息: docker network inspect pknet
3.映射数据目录
容器中的PXC节点映射数据目录的解决办法就是创建Docker卷对应pxc容器与宿主机的数据映射或者创建存储并修改权限。
#创建Docker卷对应pxc容器与宿主机的数据映射 docker volume create --name n1 docker volume create --name n2 docker volume create --name n3 docker volume create --name n4 docker volume create --name n5
#创建存储并修改权限: 放在/data/mysql_cluster可自行调整 mkdir -p /data/mysql_cluster cd /data/mysql_cluster #mkdir n1 n2 n3 n4 n5 && chmod -R 777 n1 n2 n3 n4 n5 #创建日志目录-可选 mkdir logs && cd logs mkdir n1 n2 n3 n4 n5 && chmod -R 777 n1 n2 n3 n4 n5
# 查看数据卷 docker inspect n1
# 删除数据卷: docker volume rm n1
4.创建PXC容器
docker-compose.yml如下:
version: "3.7" services: node1: image: percona/percona-xtradb-cluster:8.0.23 container_name: node1 restart: always privileged: true ports: - "3316:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 存储数据 volumes: - /data/mysql_cluster/n1:/var/lib/mysql - /data/mysql_cluster/logs/n1:/var/log/mysql networks: default: ipv4_address: 10.139.10.1 node2: image: percona/percona-xtradb-cluster:8.0.23 container_name: node2 restart: always privileged: true ports: # IP不要冲突 - "3326:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 第2台以后增加此配置 - CLUSTER_JOIN=node1 # 存储数据 volumes: - /data/mysql_cluster/n2:/var/lib/mysql - /data/mysql_cluster/logs/n2:/var/log/mysql networks: default: # IP不要相同 ipv4_address: 10.139.10.2 node3: image: percona/percona-xtradb-cluster:8.0.23 container_name: node3 restart: always privileged: true ports: # IP不要冲突 - "3336:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 第2台以后增加此配置 - CLUSTER_JOIN=node1 # 存储数据 volumes: - /n3:/var/lib/mysql - /data/mysql_cluster/logs/n3:/var/log/mysql networks: default: # IP不要相同 ipv4_address: 10.139.10.3 node4: image: percona/percona-xtradb-cluster:8.0.23 container_name: node4 restart: always privileged: true ports: # IP不要冲突 - "3346:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 第2台以后增加此配置 - CLUSTER_JOIN=node1 # 存储数据 volumes: - /data/mysql_cluster/n4:/var/lib/mysql - /data/mysql_cluster/logs/n4:/var/log/mysql networks: default: # IP不要相同 ipv4_address: 10.139.10.4 node5: image: percona/percona-xtradb-cluster:8.0.23 container_name: node5 restart: always privileged: true ports: # IP不要冲突 - "3356:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 第2台以后增加此配置 - CLUSTER_JOIN=node1 # 存储数据 volumes: - /data/mysql_cluster/n5:/var/lib/mysql - /data/mysql_cluster/logs/n5:/var/log/mysql networks: default: # IP不要相同 ipv4_address: 10.139.10.5 networks: default: external: name: pknet
用docker-compose启动
# 先启动node1,能够正常连接后再启动其他节点 docker-compose -p mysql -f docker-compose-mysql.yml up -d node1 # 查看日志 docker logs -f node1 # 等3分钟左右,工具连接mysql成功后再做后续步骤 1. 启动node2 docker-compose -p mysql -f docker-compose-mysql.yml up -d node2 # 查看日志 docker logs -f node2 # 报ssl证书错误 2. 停止 docker stop node2 3. 复制node1的认证文件,以确保所有node的认证相同(不要在up前复制) cp n1/*.pem n2/ 4. 重启node docker-compose -p mysql -f docker-compose-mysql.yml up -d node2 5. 工具连接node2,测试是否正常 # 重复以上1-4启动 node3 1. 启动node3 docker-compose -p mysql -f docker-compose-mysql.yml up -d node3 # 查看日志 docker logs -f node3 # 报ssl证书错误 2. 停止 docker stop node3 3. 复制node1的认证文件,以确保所有node的认证相同(不要在up前复制) cp n1/*.pem n3/ 4. 重启node docker-compose -p mysql -f docker-compose-mysql.yml up -d node3 5. 工具连接node3,测试是否正常 # 剩余node4和node5都是一样的启动方式
4.2 PXC集群的相关问题整理
1、必须主节点能连接上,再去创建其他节点
因为主节点创建之后,它需要初始化PXC集群环境,生成各种配置文件,所以消耗的时间比较长,你等待一分钟左右的时间,然后用客户端连接主节点,如果能连接上,说明主节点已经创建成功。这时候再去创建其他PXC节点。如果你刚创建完主节点,就去创建其他节点。因为主节点还不能正常访问,其他从节点连接不上主节点,无法加入PXC集群,所以你创建的所有从节点都处在闪退的状态。正确的做法是每创建一个节点,能用客户端访问了,再去创建下一个节点。
2、为什么前几个PXC节点都好用,创建到最后一个节点的时候,所有PXC节点都不能用了?
这是因为你的虚拟机内存太小了,建议你设置更大的内存,因为PXC集群比较占用内存,如果内存不够,PXC集群就会罢工。
3、为什么重启电脑之后,重新运行PXC容器,都处在闪退的状态?
避免VM虚拟机挂起恢复之后,Docker虚拟机断网 vi /etc/sysctl.conf 文件中添加`net.ipv4.ip_forward=1`这个配置 #重启网络服务 systemctl restart network
4.3 PXC集群测试
PXC集群的任意节点都是可读可写的,在DB1中新建数据库bdyh-test,在其他节点中刷新,也能看到bdyh-test。
五、数据库负载均衡
PXC集群的任意节点都是可读可写的,一旦PXC集群数据库上线之后,我们不能把所有数据库请求都发送给一个数据库节点,PXC集群中的所有节点都应该来参与数据库请求的 处理,实现数据库请求均匀的发送给每一个数据库节点-负载均衡。
5.1 数据库负载均衡的必要性
虽然搭建了集群,但是不使用数据库负载均衡,单节点处理所有请求,负载高、性能差
使用Haproxy做负载均衡,请求被均匀的分发给每个节点,单节点负载点,性能好
5.2 负载均衡插件对比
5.3 Haproxy
1. 安装Haproxy镜像,采用2.4.2版本
docker pull haproxy:2.4.2
2. 创建haproxy用户用于心跳测试
在任意数据库节点执行以下语句: # 1台创建,其他会自动同步 CREATE USER 'haproxy'@'%' IDENTIFIED BY '';
3. 创建haproxy.cfg配置文件
global #日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info log 127.0.0.1 local5 info #守护进程运行 daemon defaults log global mode http #日志格式 option httplog #日志中不记录负载均衡的心跳检测记录 option dontlognull #连接超时(毫秒) timeout connect 50000 #客户端超时(毫秒) timeout client 50000 #服务器超时(毫秒) timeout server 50000 #监控界面 listen admin_stats #监控界面的访问的IP和端口 bind 0.0.0.0:8888 #访问协议 mode http #URI相对地址 stats uri /dbs #统计报告格式 stats realm Global\ statistics #登陆帐户信息 stats auth admin:123456 #数据库负载均衡 listen proxy-mysql #访问的IP和端口 bind 0.0.0.0:3306 #网络协议 mode tcp #负载均衡算法(轮询算法、后面的权重不会生效) #轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source balance roundrobin #日志格式 option tcplog #在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测 option mysql-check user haproxy server MySQL_1 10.139.10.1:3306 check weight 1 maxconn 2000 server MySQL_2 10.139.10.2:3306 check weight 1 maxconn 2000 server MySQL_3 10.139.10.3:3306 check weight 1 maxconn 2000 server MySQL_4 10.139.10.4:3306 check weight 1 maxconn 2000 server MySQL_5 10.139.10.5:3306 check weight 1 maxconn 2000 #使用keepalive检测死链 option tcpka
4. 创建Haproxy容器
1.编写docker-compose文件
version: "3.7" services: haproxy1: image: haproxy:2.4.2 container_name: h1 restart: always privileged: true ports: - "4001:8888" - "4002:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 存储数据 volumes: # haproxy.ini在./haproxy目录下 - /data/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg networks: default: ipv4_address: 10.139.10.6 haproxy2: image: haproxy:2.4.2 container_name: h2 restart: always privileged: true ports: - "4003:8888" - "4004:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=xiaohezi@2023 - XTRABACKUP_PASSWORD=123456 # 集群名,要一致 - CLUSTER_NAME=PXC # 存储数据 volumes: # haproxy.ini在./haproxy目录下 - /data/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg networks: default: ipv4_address: 10.139.10.7 networks: default: external: name: pknet
2.启动
docker-compose -p haproxy -f docker-compose-haproxy.yml up -d
3.访问
监控页面访问:http://192.168.7.62:4001/dbs admin 123456
5. 测试haproxy
Haproxy并不存储任何数据,只做请求的转发,请求发给Haproxy,Haproxy会将请求转发给真实的数据库节点,在Haproxy中新建一张测试表user, Haproxy会轮询将请求转发给DB1或DB2或DB3或DB4或DB5,不管发给谁,执行完成后,因为有同步机制,会进行节点之间的同步。
Mysql连接工具中创建连接192.168.7.62:4002 root xiaohezi@2023
5.4 负载均衡的高可用方案
1. 为什么采用双机热备?
单节点Haproxy不具备高可用,必须要有冗余设计
通过关键技术:虚拟IP可解决
2. 利用Keepalived实现双机热备
Keepalived抢占虚拟ip,Keepalived运行的时候会抢占虚拟ip,谁快谁就能抢到虚拟ip,抢到的虚拟ip的Keepalived所在的容器叫做主服务器,没有抢到的叫做备服务器,备服务器处于等待。两个Keepalived之间是有心跳检测的,若是备服务器发送给主服务器的心跳检测没有响应,意味着主服务器可能出现了故障,这个时间备服务器就有权吧虚拟ip抢到手,一个挂掉没有关系,另一个会接替工作。
3. Haproxy双机热备方案
4. 在Haproxy容器中安装Keepalived,设置虚拟IP
#进入h1容器 docker exec -it h1 bash #更新软件包 apt-get update #安装VIM apt-get install vim #安装Keepalived apt-get install keepalived #编辑Keepalived配置文件(参考下方配置文件)或在宿主机上编辑好拷贝进容器 vim /etc/keepalived/keepalived.conf 或 docker cp keepalived.conf h1:/etc/keepalived/ #启动Keepalived service keepalived start #宿主机执行ping命令 ping 10.139.10.201
“注意事项:云主机不支持虚拟IP,另外很多公司的网络禁止创建虚拟IP(回家创建),还有宿主机一定要关闭防火墙和SELINUX,很多同学都因为这个而失败的,切记切记
”
keepalived.conf内容: vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 10.139.10.201 } }
#进入h2容器 docker exec -it h2 bash #更新软件包 apt-get update #安装VIM apt-get install vim #安装Keepalived apt-get install keepalived #编辑Keepalived配置文件(参考下方配置文件)或在宿主机上编辑好拷贝进容器 vim /etc/keepalived/keepalived.conf 或 docker cp keepalived.conf h2:/etc/keepalived/ #启动Keepalived service keepalived start #宿主机执行ping命令 ping 10.139.10.201
keepalived.conf内容: vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 10.139.10.201 } }
5. 宿主机安装Keepalived,实现双机热备
#宿主机执行安装Keepalived yum -y install keepalived #修改Keepalived配置文件 vi /etc/keepalived/keepalived.conf #启动Keepalived service keepalived start
Keepalived配置文件如下:
vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.7.150 } } virtual_server 192.168.7.150 8888 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 10.139.10.201 8888 { weight 1 } } virtual_server 192.168.7.150 3306 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 10.139.10.201 3306 { weight 1 } }
采用虚拟ip查看监控:192.168.7.150:8888
通过虚拟ip去连接:
6. 测试双机热备
#暂停h1容器,看能否正常提交数据,并在数据库节点中看到 docker pause h1 #恢复运行 docker unpause h1
六、总结
本文介绍了MySQL的高可用集群方案—Percona XtraDB Cluster(PXC),与其他集群方案相比,PXC具有方向明确、坚如磐石等优势。文章详细介绍了PXC的概念、原理、优势,并提供了环境搭建和PXC容器的创建步骤。对PXC集群有需求的读者可以参考本文进行搭建和配置。