1.说明
- PXC的版本是5.7.43
- 使用三台机器:192.168.50.9 、192.168.50.18 、192.168.50.245
- 三台机器都已经安装Docker
- 调整下主机的文件句柄,防止mysql连接数不够
ulimit -HSn 65535
2. 基础准备
2.1 主机名更改
建议每台机器的主机名设置下,设置为不同的名称,方便管理。
shell
# 查看主机名
hostname
#设置主机名
hostnamectl set-hostname xxx
2.2 镜像导入
因为我这边是离线的部署方式,对应的镜像包已经压缩为tar包了,如果有需要可以联系我。如果自行搭建,机器如果是连接网络的直接可以docker pull
下。
shell
cd /home/HA/pxc && docker load -i swarm.tar && docker load -i percona-xtradb-cluster.tar
有网络的话,执行如下的命令拉取镜像
shell
docker pull percona/percona-xtradb-cluster:5.7.43
docker pull swarm
2.3 swarm集群创建
50.9机器执行docker swarm init
,会得到如下的图:
其他两台机器分别执行join语句即可加入集群。
如遇如下报错: 可以先执行docker swarm leave
,然后再执行join。
验证节点是否都加入,执行docker node ls
2.4 集群间网络创建
在init机器执行
shell
docker network create -d overlay --attachable mysql_network
3. PXC安装
3.1 配置文件
每台机器执行如下命令,将配置文件拷贝对应目录
shell
mkdir -p /home/mysql/config && cp /home/HA/pxc/my.cnf /home/mysql/config/
其中my.cnf内容如下:
text
[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 = utf8mb4
个人踩坑的点:因为项目用到canal,但是PXC集群间binlog不同步,研究后发现添加log_slave_updates 、wsrep_provider_options='repl.commit_order =3;gcache.size=4096M' 、wsrep_log_conflicts 这几个参数解决了该问题。其他server-id每台机器需要更改为不同的。
3.2 安装
在50.9执行如下命令,进行pxc的主节点初始化。
shell
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分别执行如下命令:
shell
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.43
shell
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=pn3 --net=mysql_network \
percona/percona-xtradb-cluster:5.7.43
即加入的节点只需要调整自己的name就可以了。 在mysql的客户端连接A机器,ip:3306,账密:root/3er4#ER$,执行如下命令查看连接节点数量:
sql
show status like '%wsrep_incoming_addresses%';
可以看到3个节点连接正常。
3.3 常见故障处理
-
非主节点宕机
非主节点宕机,即join进去的节点挂了后,只需要重启容器即可。
-
主节点宕机
主节点宕机的处理比较复杂,得需要先停止另外一个节点,比如18,这样245的机器就是最后一个退出集群的节点了。
docker inspect mysql_data
找到pxc的data文件,然后修改grastate.dat,将safe_to_bootstrap改为1,然后通过docker rm -f xx
干掉原来的容器,通过上面的安装步骤,将pn1节点初始化再该机器,然后其他两个节点进行加入,即可。
4. 将pxc进行负载均衡
4.1 利用Nginx进行负载均衡(不推荐)
因为这样业务再sql失败如果没有重试机制的话会丢数据的。 Nginx配置文件如下:
conf
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;
}
}
4.2 Haproxy进行负载均衡
因为有心跳机制,所以有异常后会第一时间剔除。
- 创建mysql心跳检查用户
sq;
#指定数据库
use mysql;
#创建用户
create user 'haproxy'@'%' identified by '';
# 刷新权限
flush privileges;
- 修改配置文件haproxy.cfg
conf
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代替)
- 启动haproxy
shell
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
5.最后说明
真正的高可用,还是需要keepalived+haproxy进行多机部署,防止出现单点故障。后面会介绍Docker部署Keepalived