关于java:超详细干货DockerPXCHaproxy搭建高可用强一致性的MySQL集群

25次阅读

共计 9106 个字符,预计需要花费 23 分钟才能阅读完成。

前言

干货又来了,全程无废话,可先看目录理解。

MySQL 搭建集群最常见的是 binlog 形式,但还有一种形式是强一致性的,能保障集群节点的数据肯定可能同步胜利,这种形式就是 pxc,本篇就应用图文形式一步步展现具体的搭建步骤及最终成果。

搭建

本次搭建集群环境以 5 节点 MySQL 为例

1、装置 pxc 镜像

拉取 pxc 镜像

docker pull percona/percona-xtradb-cluster

镜像名称太长,批改一下:

docker tag percona/percona-xtradb-cluster pxc

删除之前的:

docker rmi percona/percona-xtradb-cluster

2、创立外部网络

创立内部网段,24 位,名称 net1:

docker network create --subnet=172.18.0.0/24 net1

查看 net1 网段:

docker inspect net1

删除 net1:(这里不执行,留作参考。)

docker network rm net1

3、创立 docker 数据卷

因为 pxc 不反对映射目录,所以采纳映射数据卷的形式。

创立数据卷叫 v1,这里 5 个节点,所以创立 5 个数据卷:

docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5

查看 v1 数据卷在宿主机的地位:

docker inspect v1

删除数据卷 v1:(这里不执行,留作参考。)

docker volume rm v1

4、创立 pxc 容器

这里最好先把备份数据的数据卷创立进去,而后也映射到宿主机,这样当前做热备份的时候就不必删掉容器节点从新再创立容器并映射备份目录了。

做备份数据的数据卷:

docker volume create backup1
docker volume create backup2
docker volume create backup3
docker volume create backup4
docker volume create backup5

开始创立 5 个 MySQL 节点

命令参数阐明:端口 3306,明码 123456,集群名称 PXC,同步数据明码 123456,映射数据目录到宿主机的 v1 数据卷,给予最高权限,名称叫 node1,网段为 net1,ip 指定为 172.18.0.2,运行的镜像是 pxc。

1)、创立第 1 个 MySQL 节点

这里要留神:肯定要等到第一个节点创立并通过客户端连贯胜利,能力持续创立其它的节点,否则因为找不到 node1 同步库,其它节点创立时会闪退!
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -v v1:/var/lib/mysql -v backup1:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc

2)、创立第 2 个 MySQL 节点

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql -v backup2:/data --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc

3)、创立第 3 个 MySQL 节点

docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql -v backup3:/data --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc

4)、创立第 4 个 MySQL 节点

docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql -v backup4:/data --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc

5)、创立第 5 个 MySQL 节点

docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql -v backup5:/data --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc

5、验证 PXC 集群

连贯 5 个数据库节点:

在 DB1 中新建一个数据库 test,新建一张表 tb_student,新建两条数据。

提交后,看其它四个节点是否同步:

发现全副同步胜利!

6、拉取 Haproxy 镜像

docker pull haproxy

7、编写 Haproxy 配置文件

在宿主机上编写:

vim /data/software/haproxy/haproxy.cfg

配置文件如下:(拷贝到 Linux 中去的时候肯定要记得把换行符删掉,否则报错。)

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     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 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)、option 局部,记得在 MySQL 创立一个没有权限的用户 haproxy;

   CREATE USER ‘haproxy’@’%’ IDENTIFIED BY ”;

2)、server 局部,记得这里 3306 是容器的端口,不是宿主机的端口。

8、创立 Haproxy 容器并启动

创立两个,前面应用 Keepalived 做高可用。

1)、创立第 1 个 Haproxy 负载平衡服务器

4001 映射 8888 端口,8888 是监控界面端口,haproxy 端口用 4002 映射 3306;

因为宿主机上之前装置 pxc 曾经占用了 3306,/data/software/haproxy 是宿主机上创立的目录,映射 haproxy 容器寄存配置文件的目录 /usr/local/etc/haproxy;

名称起 h1,前面要做高可用,给所有权限,网段和 pxc 对应,也是 net1,ip 设为 172.18.0.7,镜像是 haproxy。

docker run -it -d -p 4001:8888 -p 4002:3306 -v /data/software/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy

进入 h1 容器,启动 Haproxy。

# 进入 h1 容器
docker exec -it h1 bash
# 启动 Haproxy
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
2)、创立第 2 个 Haproxy 负载平衡服务器

docker run -it -d -p 4003:8888 -p 4004:3306 -v /data/software/haproxy:/usr/local/etc/haproxy --name h2 --privileged --net=net1 --ip 172.18.0.8 haproxy

进入 h2 容器,启动 Haproxy。

# 进入 h2 容器
docker exec -it h2 bash
# 启动 Haproxy
haproxy -f /usr/local/etc/haproxy/haproxy.cfg

9、浏览器拜访 Haproxy

拜访地址:http://192.168.239.132:4001/dbs

这里的 4001 是创立容器时映射的 8888 端口,dbs 是 haproxy.cfg 中的 stats uri。

测试下敞开一个节点:docker stop node1

刷新页面:发现 node1 就变红了,示意断开了。

留神:

docker start node1 重新启动节点,会有闪退问题,起不起来,解决办法:

先停掉并删掉这个容器,别缓和,没让你删除 v1 数据卷,所以数据丢不了,再从新建一个容器,数据卷还是指向之前那个数据卷,然而 cluster-join=node2,轻易和一个失常的一般节点同步就行了。

10、验证形式

数据库连贯 haproxy 试试加一条数据,转发申请后其余数据库是否同步。

H1 外面批改一条数据或增加数据后,转发申请到其余数据库,发现能够,并且 pxc 会同步数据,每个节点都同步了,这就阐明咱们的 Haproxy 搭建是 OK 的。

11、Haproxy 双机热备

1)、Haproxy 容器内装置 Keepalived 并设置虚构 IP

注意事项:

云主机不反对虚构 IP,另外很多公司的网络禁止创立虚构 IP(回家创立), 这个须要分割公司的网络管理员,让他凋谢你要设置的虚构 IP 就能够了。还有宿主机肯定要敞开防火墙和 SELINUX,很多人都因为这个而失败的,切记切记。

h1 容器装置 Keepalived,apt 减速可自行百度。

# 进入 h1 容器
docker exec -it h1 bash
# 更新软件包
apt-get update
# 装置 VIM
apt-get install -y vim
# 装置 Keepalived
apt-get install keepalived
# 编辑 Keepalived 配置文件(参考下方配置文件)vim /etc/keepalived/keepalived.conf
# 启动 Keepalived
service keepalived start
# 宿主机执行 ping 命令,看是否能够 ping 通虚构 IP。ping 172.18.0.201

配置文件内容如下:

vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {172.18.0.201}
}

阐明:

state=MASTER,示意主服务,会被动争抢虚构 ip;

interface=eth0,是 docker 容器内的网卡名称,要映射宿主机网卡,所以宿主机也要装一个 Keepalived;

virtual_router_id=51,示意虚构路由 id,0-255 都能够;

priority=100,示意权重,越高就阐明优先级越高,越容易抢到虚构 ip;

advert_int=1,示意心跳检测的频率,这里就是 1 秒检测一次;

authentication,就是心跳检测拜访的时候须要通过的账号密码;

virtual_ipaddress,这就是虚构 ip 的设置。

h2 容器装置 Keepalived

# 进入 h2 容器
docker exec -it h2 bash
# 更新软件包
apt-get update
# 装置 VIM
apt-get install -y vim
# 装置 Keepalived
apt-get install keepalived
# 编辑 Keepalived 配置文件
vim /etc/keepalived/keepalived.conf
# 启动 Keepalived
service keepalived start
# 宿主机执行 ping 命令,看是否能够 ping 通虚构 IP。ping 172.18.0.201

配置文件内容如下:

vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {172.18.0.201}
}
2)、宿主机装置 Keepalived 并设置虚构 ip

次要作用是为了转发到 haproxy 容器内的虚构 ip

# 宿主机执行装置 Keepalived
yum -y install keepalived
# 批改 Keepalived 配置文件
vi /etc/keepalived/keepalived.conf
# 启动 Keepalived
service keepalived start

keepalived.conf 配置如下:

记得网卡肯定要写对,用 ip addr 查看。

阐明:

1)、virtual_ipaddress 就是宿主机设置的虚构 ip;

2)、virtual_server 前面的 ip 和端口就是宿主机的虚构 ip 和要转发的端口;

3)、real_server,就是宿主机转发到 haproxy 容器内的虚构 ip,以及转发到的端口。

这里的配置含意就是:宿主机设置虚构 ip 为 192.168.239.150,申请转发到 haproxy 容器的 172.18.0.201 虚构 ip,端口转发的是 8888,3306.

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.239.150}
}

virtual_server 192.168.239.150 8888 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 172.18.0.201 8888 {weight 1}
}

virtual_server 192.168.239.150 3306 {
    delay_loop 3
    lb_algo rr 
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 172.18.0.201 3306 {weight 1}

}
3)、验证

宿主机 ping 192.168.239.150,看是否能通;

近程机 ping 192.168.239.150,看是否能通;

浏览器拜访 http://192.168.239.150:8888/dbs,看是否能连上 mysql 集群;

一直刷新,看 for pid 是否会变动,会变动阐明平衡起作用了;

用客户端连贯 192.168.239.150,试试增加或批改数据,看集群节点是否会同步数据;

docker pause h1,将 h1 容器暂停,再试一下 4 的做法,看是否同步;

docker unpause h1,复原 h1 容器。

12、热备份数据

因为这个工具是装置在 mysql 容器内的,所以最好先创立一个数据卷,映射容器内备份的某个目录,这样在宿主机上就能看到备份了。

# 宿主机创立数据卷
docker volume create backup

如果创立 mysql 容器时,没有映射备份目录,那么要先停掉容器,而后删掉,再从新创立容器并映射备份目录。

# 停掉容器
docker stop node1

# 删除容器
docker rm node1

创立容器,映射备份目录,这里的 backup 就是下面创立的数据卷。这里留神 node1 进行后,从新创立须要以一般节点形式启动,否则会闪退,因为 node1 自身是主节点,进行后主节点就转移到其它节点去了,这里我和 node2 节点同步。

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node2 -v v1:/var/lib/mysql -v backup:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc

热备份数据

进入 node1 容器

docker exec -it node1 bash

更新软件包,这里执行如果提醒没有权限 (Permission denied),就用 docker exec -it -u 0 node1 bash 重登录试试,示意以 root 用户登陆 docker 内 linux。

apt-get update

装置热备工具

apt-get install percona-xtrabackup-24

全量热备

innobackupex --user=root --password=123456 /data/backup/full

13、冷还原数据

进行节点,并删除节点。

docker stop node1
docker stop node2
docker stop node3
docker stop node4
docker stop node5

docker rm node1
docker rm node2
docker rm node3
docker rm node4
docker rm node5

删除数据卷

docker volume rm v1
docker volume rm v2
docker volume rm v3
docker volume rm v4
docker volume rm v5

从新创立数据卷

docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5

启动容器

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -v v1:/var/lib/mysql -v backup1:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc

node1 容器中删除 MySQL 的数据并还原

# 删除数据
rm -rf /var/lib/mysql/*

# 清空事务
innobackupex --user=root --password=123456
--apply-back /data/backup/full/2019-02-17_08-53-07/

# 还原数据
innobackupex --user=root --password=123456 
--copy-back /data/backup/full/2019-02-17_08-53-07/

重新启动容器

docker stop node1
docker start node1

这个时候,可能会闪退,查看日志谬误如下:

说是对 ibdata1 这文件没有写入权限,

那咱们无妨全局搜一下这文件,看是哪个目录的:

find / -name ibdata1,能够看到在 backup 备份目录和 v1 的数据卷目录都有。

那咱们间接给这两个目录最大权限:

chmod -R 777 /var/lib/docker/volumes/backup/_data

chmod -R 777 /var/lib/docker/volumes/v1/_data

而后再次启动容器。

启动后,验证后面「node1 容器中删除 MySQL 的数据并还原」这一步看是否还原胜利,用工具连贯数据库查看。

总结

这些环境的搭建其实是偏差于运维层面的,很多 Java 工程师可能感觉用不上,但不会搭建和你齐全不晓得是两码事,有一篇手记存底,空闲之余本人尝试搭建下,对你日后的职业倒退肯定是有益处的。

分享

8 年多工作及学习过程中在云笔记中记录了很多内容,我空闲之余都做了下整顿,本篇也是其中之一,有感兴趣的敌人能够下载看看,什么时候用到了打开说不定就能节俭很多工夫。

链接: https://pan.baidu.com/doc/sha…

提取码: bxaa


自己原创文章纯手打,感觉有一滴滴帮忙就请点个赞和珍藏吧~

自己继续分享理论工作教训和支流技术,喜爱的话能够关注下哦~

更多最新技术文章可关注 GZH:【Java 分享客栈】

正文完
 0