此文档用于记录基于docker搭建mysql集群的过程。这里不介绍docker的安装,如有需要请移步到电梯直达。
环境: centos7.6 docker-ce19.03.12 percona/percona-xtradb-cluster:5.7.20
pxc介绍
PXC全称Percona XtraDB Cluster,它提供了MySQL高可用的一种实现方案。PXC集群是以节点组成,推荐奇数个节点(至少3个以上),集群中的每个节点都包含完整的数据,并且所有节点都是可读可写的。PXC集群方案能够保证数据的强一致性,事务在所有集群节点要么同时提交,要么同时不提交。
环境
主机ip |
主服务 |
安装方式 |
主机系统 |
172.16.77.46 |
mysql |
docker-ce |
Centos7.6 |
搭建pxc集群
拉取PXC镜像
1
2
3
4
|
# 拉取镜像
$ docker pull percona/percona-xtradb-cluster:5.7.20
#修改镜像名称
$ docker tag percona/percona-xtradb-cluster:5.7.20 pxc
|
创建docker内部网络
1
2
3
4
5
6
|
# 创建内部网段
$ docker network create --subnet=172.18.0.0/24 net1
# 查看网段相关信息
$ docker network inspect net1
# 下面为删除网段
# $ docker network rm net1
|
创建docker卷
pxc运行在docker容器中,如果直接使用宿主机目录映射数据目录,会导致容器启动闪退。这里就需要使用docker卷来映射目录。
1
2
3
4
5
6
7
8
9
10
|
# 创建数据卷
$ docker volume create v1
$ docker volume create v2
$ docker volume create v3
$ docker volume create v4
$ docker volume create v5
# 查看docker卷信息
$ docker volume inspect volume_name
# 下面命令为删除docker卷
# $ docker volume rm volume_name
|
创建pxc容器
注意:这里启动时,我将mysql的配置文件的目录映射到本地目录了,因为我们可能有修改配置文件的需要。经实际操作发现映射到本地时会清除容器内对应目录下的文件,需要提前单独起一个容器将该目录下的文件取出来放在宿主机的对应目录下即可。如果没有此需求,就将下面命令中的-v /home/mysql/conf.d:/etc/mysql/conf.d
删除
1
2
3
4
5
6
7
8
|
$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=bnsbdlmysql -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=bnsbdlmysql -v v1:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
$ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=bnsbdlmysql -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=bnsbdlmysql -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc
$ docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=bnsbdlmysql -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=bnsbdlmysql -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
$ docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=bnsbdlmysql -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=bnsbdlmysql -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc
$ docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=bnsbdlmysql -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=bnsbdlmysql -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
# 查看正在运行的容器
$ docker ps
|
使用Navicat测试连接pxc集群节点
可以创建个数据库看看是否其他节点都有,测试成功后再进行以下配置。
负载均衡方案
负载均衡的必要性
- 如果不使用数据库负载均衡,单节点处理所有请求,负载高,性能差
- 使用Haproxy做负载均衡,请求被均匀分发给每个节点,单节点负载低,性能好
安装Haproxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
$ mkdir /home/haproxy
$ vim /home/haproxy/haproxy.cfg
global
# 工作目录
chroot /usr/local/etc/haproxy
# 日志文件,使用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 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 Clobal\ 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 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
# 使用keepalive检测死链
option tcpka
|
1
2
3
4
5
|
$ docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/haproxy:/usr/local/etc/haproxy --name haproxy-1 --privileged --net=net1 --ip 172.18.0.7 haproxy
#进入容器后,加载配置文件
$ docker exec -it haproxy-1 /bin/bash
$ haproxy -f /usr/local/etc/haproxy/haproxy.cfg
|
- 在数据库创建一个haproxy的用户,不需要设置密码。Haproxy使用这个账号对mysql数据库心跳检测
- 登录haproxy网页端,http://172.16.77.46:4001/dbs
高可用负载均衡方案
单节点haproxy不具备高可用,需要有冗余设计
虚拟IP技术
haproxy双机互备离不开一个关键的技术,这个技术是虚拟IP,linux可以在一个网卡内定义多个虚拟IP,得把这些IP地址定义到一个虚拟IP。
利用keepalived实现双机热备
定义出来一个虚拟IP,这个方案叫双机热备,准备2个keepalived,keepalived 就是为了抢占虚拟IP的,谁手快谁能抢到,没抢到的处于等待的状态。抢到的叫做主服务器,未抢到的叫做备服务器。两个keepalived之前有心跳检测的,当备用的检测到主服务挂了,就立马抢占虚拟IP。
Haproxy双机热备方案
安装keepalived
- keepalived必须在haproxy所在的容器之内,也可以在docker仓库里面下载一个haproxy-keepalived的镜像。这里直接在容器内安装keepalived。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
$ docker exec -it haproxy-1 /bin/bash
$ apt-get update -y
$ apt-get install iputils-ping vim net-tools procps -y
$ apt-get install keepalived -y
# 编写keeplived配置文件,路径为/etc/keepalived/keepalived.conf
$ vi /etc/keepalived/keepalived.conf
# VI_1 名称可以自定义
vrrp_instance VI_1 {
#定义节点属性 Keepalived的身份(MASTER主服务,BACKUP备服务器)。主服务要抢占虚拟IP,备服务器不会抢占虚拟IP。
state MASTER
#定义网卡设备 eth0是网卡名字,Docker虚拟机的网卡。可以在容器用 ip a查看
interface eth0
#定义组vriid 虚拟路由标识,MASTER和BACKUP的虚拟路由标识必须一致。标识可以是0~255
virtual_router_id 51
#定义权重 MASTER权重 要 高于BACKUP,数据越大优先级越高
priority 100
#定义心跳检测时间1秒 MASTER与BACKUP节点间同步检查(心跳检测)的时间间隔,单位为秒。主备之间必须一致。
advert_int 1
#定义组用户密码 主从服务器验证方式。主备必须使用相同的密码才能正常通信。心跳检测登录Keepalived节点,开放账号密码。
authentication {
auth_type PASS
auth_pass 123456
}
#定义docker内ip地址,必须要在和haproxy同一个网段 两个keepalived同时抢一个虚拟ip 可以设置多个虚拟IP地址,每行一个
virtual_ipaddress {
172.18.0.201
}
}
|
1
2
3
4
5
6
7
|
$ service keepalived start
# 宿主机ping这个ip
$ ping 172.18.0.201
PING 172.18.0.201 (172.18.0.201) 56(84) bytes of data.
64 bytes from 172.18.0.201: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 172.18.0.201: icmp_seq=2 ttl=64 time=0.038 ms
|
创建haproxy2容器。并配置和haproxy相同的环境,这里不再过多赘述。
注意:每次如果某一个haproxy服务宕机,重启的时候需要重新进入paroxy容器加载配置文件 并且重启keepalived
宿主机安装配置keeplived
1
|
$ yum -y install keepalived$ mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak$ vi /etc/keepalived/keepalived.confvrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.77.47 #虚拟ip 需要和宿主机ip在同一网段 }}#接受监听数据来源的端口,网页入口使用virtual_server 172.16.77.47 8888 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP#把接受到的数据转发给docker服务的网段及端口,由于是发给docker服务,所以和docker服务数据要一致 real_server 172.18.0.201 8888 { weight 1 }}#接受数据库数据端口,宿主机数据库端口是3306,所以这里也要和宿主机数据接受端口一致virtual_server 172.16.77.47 3306 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP#同理转发数据库给服务的端口和ip要求和docker服务中的数据一致 real_server 172.18.0.201 3306 { weight 1 }}
|
1
|
$ systemctl start keepalived $ systemctl enable keepalived
|
- 访问haproxy页面,http://172.16.77.47:8888/dbs
相关问题处理
mysql节点启动闪退
- 现象:重启pxc节点发现节点容器无法启动
- 解决办法
1
2
3
4
5
6
7
8
|
# 进入到容器挂载点的目录下,例如node1 这里取决于你的docker存储目录
$ cd /home/docker/docker-data/volumes/v1/_data
$ vi grastate.dat
# GALERA saved state
version: 2.1
uuid: dfc7776f-f628-11ea-907f-9f2f320bb959
seqno: -1
safe_to_bootstrap: 0 #将这里的0改为1 然后保存再启动
|
参考链接
https://idig8.com/2019/02/01/shizhanpiankaiyuanxiangmudockerhuayunweibushu-dajianmysqljiqunsi/
Author
dylan
LastMod
2021-05-10
License
如需转载请注明文章作者和出处。谢谢!