因为公司需要搭建mysql集群,本来使用原生的mysql镜像搭建了一个简单的主从集群,后来发现使用pxc集群更加方便快捷,而且数据同步性能更强,所以尝试搭建一个pxc集群。
Percona XtraDB Cluster(PXC集群),提供了MySQL高可用,多节点同时读写的解决方案。
PXC是基于Galera协议的高可用方案。
Galera是Codership提供的多主数据同步复制机制,可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据一致性。
PXC集群是由节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上。每个节点都包含完整的数据副本。
PXC最大的优势:强一致性、无同步延迟
PXC的优点
1)服务高可用;
2)数据同步复制(并发复制),几乎无延迟;
3)多个可同时读写节点,可实现写扩展,不过最好事先进行分库分表,让各个节点分别写不同的表或者库,避免让galera解决数据冲突;
4)新节点可以自动部署,部署操作简单;
5)数据严格一致性,尤其适合电商类应用;
6)完全兼容MySQL;
PXC的缺点:
1)只支持InnoDB引擎;
2)写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功。
4)所有表都要有主键;
5)不支持LOCK TABLE等显式锁操作;
6)锁冲突、死锁问题相对更多;
准备两台以上的服务器或者虚拟机,安装docker,并且关闭selinux和防火墙,或者开启端口,pxc一般会用到4个端口
3306: # mysql 实例端口
4567: # PXC cluster 相互通讯的端口
4444: # 用于 SST(State Snapshot Transfer): 全量传输
4568: # 用于 IST(Incremental state Transfer):增量传输传送
由于一直使用的是mysql.7所以就拉取5.7版本的镜像
#拉取镜像
docker pull percona/percona-xtradb-cluster:5.7.21
因为pxc无法映射目录,所以采用的是挂载数据卷的方式,创建两个数据卷,一个是mysql数据存放卷,一个是配置存放卷
#pxc无法映射目录,只能创建数据卷,分别创建mysql数据卷和配置卷
docker volume create mysql-data
docker volume create mysql-conf
首先在master节点上创建第一个pxc节点,这里我使用的是host网络模式,所以不需要映射目录,其他方式需要映射上面的四个端口。
-v mysql-data:/var/lib/mysql 挂载mysql数据卷
-v mysql-conf:/etc/mysql 挂载mysql配置卷
-e CLUSTER_NAME=PXC 创建的集群名字
-e MYSQL_ROOT_PASSWORD=123456 mysql的root用户的密码
-e EXTRABACKUP_PASSWROD=123456 PXC 集群之间数据同步的密码
--privileged 创建的容器有读写的权限
--name=mysql-node1 创建的容器名称
--net=host 主机网络模式,容器直接使用主机的端口,无需映射
docker run -d -v mysql-data:/var/lib/mysql --restart always -e TZ=Asia/Shanghai \
-e CLUSTER_NAME=PXC -v mysql-conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=password4006087608 -e EXTRABACKUP_PASSWROD=password4006087608 \
--privileged --name=mysql-node1 --net=host percona/percona-xtradb-cluster:5.7.21
使用docker ps命令可以看到容器已经启动成功,使用navicat等工具连接
如果连接成功就表示第一个节点已经成功启动
因为项目需要要修改my.cnf里的sql_mode,这个时候我们可以去挂载的配置卷去修改my.cnf,使用inspect命令可以查看卷所在的位置
然后到/var/lib/docker/volumes/mysql-conf_data下面的my.cnf更改配置文件,然后重新启动容器
docker restart mysql-node1
启动成功后连接到服务器上执行命令查看是否修改成功
可以查看到已经修改成功,然后我们部署第二个节点
跟第一台服务器一样,创建两个数据卷,然后直接启动容器
docker run -idt -v mysql-data:/var/lib/mysql --restart always -e TZ=Asia/Shanghai \
-e CLUSTER_NAME=PXC -v mysql-conf:/etc/mysql -e CLUSTER_JOIN=192.168.3.232 \
-e MYSQL_ROOT_PASSWORD=123456 -e EXTRABACKUP_PASSWROD=123456 \
--privileged --name=mysql-node2 --net=host percona/percona-xtradb-cluster:5.7.21
然后使用docker ps命令查看是否启动,继续使用navicat工具测试能否连接成功
然后重复第一个节点的步骤,修改my.cnf然后重启
创建一个新的mysql账号,该账号后续也会用到。
CREATE USER 'haproxy'@'%' IDENTIFIED BY '';
我们是在node1节点上创建了一个haproxy账号,然后可以再node2节点的user表中查询到这个用户,至此pxc集群数据同步验证完成
如果单纯是想做pxc集群的话上面的步骤已经完成,但是想要使用负载均衡来使用pxc集群的话,我们可以使用haproxy工具
#拉取haprox镜像
docker pull haproxy
#新建目录
mkdir /data/haproxy
#新建配置文件
vi /data/haproxy/haproxy.cfg
配置文件的内容,主要还是最后的两个server需要配置前面的两个节点,weight标识权重
#haproxy.cfg配置
global
#工作目录,这边要和创建容器指定的目录对应
# chroot /usr/local/etc/haproxy
#日志文件
log 127.0.0.1 local5 info
#守护进程运行
daemon
defaults
log global
mode http
#日志格式
option httplog
#日志中不记录负载均衡的心跳检测记录
option dontlognull
#连接超时(毫秒)
timeout connect 5000
#客户端超时(毫秒)
timeout client 50000
#服务器超时(毫秒)
timeout server 50000
#监控界面
listen admin_stats
#监控界面的访问的IP和端口
bind 0.0.0.0:8888
#访问协议
mode http
#URI相对地址
stats uri /dbs_monitor
#统计报告格式
stats realm Global\ statistics
#登陆帐户信息
stats auth admin:admin
#数据库负载均衡
listen proxy-mysql
#访问的IP和端口,haproxy开发的端口为3306
#假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例
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 192.168.3.232:3306 check weight 1 maxconn 2000
server MySQL_2 192.168.3.233:3306 check weight 1 maxconn 2000
#使用keepalive检测死链
option tcpka
#在主节点创建haproxy容器
docker run -d -p 8888:8888 -p 3307:3306 -v /data/haproxy:/usr/local/etc/haproxy \
--name haproxy --privileged haproxy
输入地址 http://192.168.3.232:8808/dbs_monitor
如果出现如下图两个节点都是绿色状态则说明连接成功,两个节点都是正常的状态
然后测试负载均衡端口 ,因为我们是部署在第一个节点的服务器上,所以用navicat连接第一个节点的3307端口
然后新建一个数据库test123,可以发现node2节点也会自动新建test123数据库,说明haproxy生效,至此pxc集群搭建完成