提议每台机器的主机名设置下,设置为不同的名称,方便管理。
#查看主机名
hostname
#设置主机名
hostnamectl set-hostname xxx有网络的话,执行如下的命令拉取镜像
docker pull percona/percona-xtradb-cluster:5.7.43
docker pull swarm50.9 机器执行 docker swarm init,会得到如下的图:

swarm初始化
其他两台机器分别执行 join 语句即可加入集群。
如遇如下报错:

可以先执行 docker swarm leave,然后再执行 join。
验证节点是否都加入,执行
docker node ls
在 init 机器执行,创建集群需要的网络。
docker network create -d overlay --attachable mysql_network每台机器执行如下命令,将配置文件拷贝对应目录
mkdir -p /home/mysql/config && vi /home/mysql/config/my.cnf其中 my.cnf 内容如下:
[mysqld]
skip_ssl
federated
skip-name-resolve
default-time-zone=+08:00
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8mb4'
lower_case_table_names = 1
log_bin_trust_function_creators=1
key_buffer_size=16M
max_allowed_packet=512M
sql_mode=TRADITIONAL
max_connections = 20000
max_connect_errors = 1200
max_user_connections = 20000
group_concat_max_len = 102400
interactive_timeout = 610
wait_timeout = 610
innodb_thread_concurrency=32
innodb_buffer_pool_size=8589934592
innodb_buffer_pool_instances=4
server-id=1
binlog_format=ROW
log_bin=/var/lib/mysql/binlog
log_slave_updates
expire_logs_days = 1
wsrep_provider_options='repl.commit_order =3;gcache.size=4096M'
wsrep_log_conflicts
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
default-character-set = utf8mb4ps:由于项目用到 canal,但是 PXC 集群间 binlog 不同步,研究后发现添加log_slave_updates、wsrep_provider_options='repl.commit_order=3;gcache.size=4096M'、wsrep_log_conflicts这几个参数解决了该问题。
server-id每台机器需要更改为不同的。
在 50.9 执行如下命令,进行 pxc 的主节点初始化。
docker volume create mysql_data
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=3er4#ER$
-e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=3er4#ER$
-v mysql_data:/var/lib/mysql -v /etc/localtime:/etc/localtime
-v /home/mysql/config:/etc/percona-xtradb-cluster.conf.d
--privileged --name=pn1 --net=mysql_network
percona/percona-xtradb-cluster:5.7.43在 50.18 与 50.245 分别执行如下命令:
docker volume create mysql_data
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=3er4#ER$
-e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=3er4#ER$ -e CLUSTER_JOIN=pn1
-v mysql_data:/var/lib/mysql
-v /home/mysql/config:/etc/percona-xtradb-cluster.conf.d
--privileged --name=pn2 --net=mysql_network
percona/percona-xtradb-cluster:5.7.43docker volume create mysql_data
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=3er4#ER$
-e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=3er4#ER$ -e CLUSTER_JOIN=pn1
-v mysql_data:/var/lib/mysql
-v /home/mysql/config:/etc/percona-xtradb-cluster.conf.d
--privileged --name=pn3 --net=mysql_network
percona/percona-xtradb-cluster:5.7.43即加入的节点只需要调整自己的 name 就可以了。 在 mysql 的客户端连接 A 机器,ip:3306,账密:root/3er4#ER$,执行如下命令查看连接节点数量:
show status like '%wsrep_incoming_addresses%';
可以看到 3 个节点连接正常。


由于这样业务再 sql 失败如果没有重试机制的话会丢数据的。 Nginx 配置文件如下:
stream {
upstream mysql23306 {
hash $remote_addr consistent; #负载方法
server 192.168.50.18:3306 max_fails=5 fail_timeout=30s;
server 192.168.50.9:3306 max_fails=5 fail_timeout=30s;
server 192.168.50.245:3306 max_fails=5 fail_timeout=30s;
}
server {
listen 23306; #服务器监听端口
proxy_connect_timeout 60;
proxy_timeout 300s; #设置客户端和代理服务之间的超时时间,如果5分钟内没操作将自动断开。
proxy_pass mysql23306;
}
}由于有心跳机制,所以有异常后会第一时间剔除。
#指定数据库
use mysql;
#创建用户
create user 'haproxy'@'%' identified by '';
# 刷新权限
flush privileges;global
#工作目录
chroot /usr/local/etc/haproxy
#日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info
log 127.0.0.1 local5 info
#守护进程运行
daemon
maxconn 10000
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
#统计报告格式
stats realm Global statistics
#登陆帐户信息
stats auth admin:abc123456
#数据库负载均衡
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.0.1.2:3306 check weight 1 maxconn 2000
server MySQL_2 10.0.1.4:3306 check weight 1 maxconn 2000
server MySQL_3 10.0.1.6:3306 check weight 1 maxconn 2000
#使用keepalive检测死链
option tcpka其中最后的 server 部分的 ip,得到每个容器节点,去获取其内部容器 IP。(这样会带来一个问题,就是 PXC 故障后,重启会出现 IP 变化的情况,解决方案(没有验证过):1.可以在创建 PXC 节点的时候指定好 ip 2.可以使用宿主机 Ip 取代)
docker run -it -d -p 18888:8888 -p 13306:3306 -v /home/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=mysql_network haproxy:2.8由于部署的时候,开启 binlog,发现 binlog 的增长有点夸张,一个小时大致会有 4G 的 binlog,所以自行写了个脚本进行 binlog 的清理,具体如下。 脚本 cleanBinlog.sh 内容如下:
#!/bin/bash
cname=`docker ps -a --format "table {{.Names}}" | grep -v "NAMES"| grep pn | tr -d '
'`
echo $cname
docker exec $cname mysql -uroot -p3er4#ER$ -e "purge binary logs BEFORE DATE_SUB(now(), INTERVAL 1 HOUR );"即找到机器上 pxc 的节点,然后进入容器执行 binlog 清理,清理 1 个小时之前的 binlog。配合 linux 的定时任务,crontab -e 在最后添加 @hourly
/home/mysql/cleanBinlog.sh 即可。
