MySQL 高可用集群太难部署,我用 Docker 五分钟就搞定它!-CSDN博客


公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

af3ddc505fcd7c59e8814afdd4f9a4bd.png

1集群方案

  1. Replication

  • 速度快,但仅能保证弱一致性,适用于保存价值不高的数据,比如日志、帖子、新闻等。

  • 采用 Master-Slave 结构,在 Master 写入会同步到 Slave,能从 Slave 读出;但在 Slave 写入无法同步到 Master。

  • 采用异步复制,Master 写入成功就向客户端返回成功,但是同步 Slave 可能失败,会造成无法从 Slave 读出的结果

  • 需要该方案的请查看我的另一篇文章:『Docker 实现 MySQL 主从复制

8670b35e7a34c020fb3b693e30aadebb.png

  1. PXC (Percona XtraDB Cluster)

  • 速度慢,但能保证强一致性,适用于保存价值较高的数据,比如订单、客户、支付等。

  • 数据同步是双向的,在任一节点写入数据,都会同步到其他所有节点,在任何节点上都能同时读写。

  • 采用同步复制,向任一节点写入数据,只有所有节点都同步成功后,才会向客户端返回成功。事务在所有节点要么同时提交,要么不提交。

77f0d8175f4489fd92dc6d75cb1aa75b.png

2安装 PXC 集群

  1. 安装镜像

$ docker pull percona/percona-xtradb-cluster:5.7.33
  1. 重命名镜像(缩短镜像名称)

  1. $ docker tag percona/percona-xtradb-cluster:5.7.33 pxc

  2. # 移除原镜像  

  3. $ docker rmi percona/percona-xtradb-cluster:5.7.33

  1. 创建 net1 网段

  • 出于安全考虑,给PXC集群创建Docker内部网络

  1. # 创建网段  

  2. $ docker network create --subnet=172.18.0.0/24 net1  

  3. # 查看网段  

  4. $ docker network inspect net1  

  5. # 删除网段  

  6. $ docker network rm net1

  1. 创建五个数据卷(pxc无法直接存取宿组机的数据,所以创建五个 docker 数据卷)

  1. $ docker volume create v1  

  2. $ docker volume create v2  

  3. $ docker volume create v3  

  4. $ docker volume create v4  

  5. $ docker volume create v5  

  6. # 查看数据卷位置  

  7. $ docker inspect v1  

  8. # 删除数据卷  

  9. $ docker volume rm v1

  1. 创建 5 节点的 PXC 集群

  • 第一个节点创建完成之后,需要等 1 分钟左右才能创建后面的节点。可以通过 Navicat连接第一个节点测试下,可以连接就说明可以了

  1. # 创建第 1 个 MySQL 节点  

  2. $ docker run -d --name=mysql-node1 -p 3310:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql --net=net1 --ip 172.18.0.2 pxc  

  3. # 创建第 2 个 MySQL 节点  

  4. $ docker run -d --name=mysql-node2 -p 3311:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node1 -v v2:/var/lib/mysql --net=net1 --ip 172.18.0.3 pxc  

  5. # 创建第 3 个MySQL节点  

  6. $ docker run -d --name=mysql-node3 -p 3312:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node1 -v v3:/var/lib/mysql --net=net1 --ip 172.18.0.4 pxc  

  7. #创建第 4 个 MySQL节点  

  8. $ docker run -d --name=mysql-node4 -p 3313:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node1 -v v4:/var/lib/mysql --net=net1 --ip 172.18.0.5 pxc  

  9. # 创建第 5 个 MySQL 节点  

  10. $ docker run -d --name=mysql-node5 -p 3314:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node1 -v v5:/var/lib/mysql --net=net1 --ip 172.18.0.6 pxc

  1. 测试集

  • 通过 Navicat 连接任意一个数据库,进行增、删、改操作操作,观察其它库是否进行同步操作

c4bcc895a74a1beb402987e60310b9d3.png

3Haproxy 负载均衡

  • 虽然搭建了集群,但是不使用数据库负载均衡,单节点处理所有请求,负载高,性能差,如下图

cab769ec2e8430b542a2d9b1571a0688.png

8d36d3576c5513c4549ad18f06844794.png

点击上方图片,打开小程序,『饿了么外卖』红包免费领!

  • 使用Haproxy做负载均衡,可以将请求均匀地发送给每个节点,单节点负载低,性能好,如下图

e9e59c8123260bd27184a3f814b5e6bf.png

  1. 安装haproxy镜像

$ docker pull haproxy:2.3.13
  1. 新建目录

$ mkdir -p /home/apps/haproxy
  1. 新建 Haproxy 配置文件

  1. $ vim /home/apps/haproxy/haproxy.cfg  

  2. # 增加以下内容  

  3. global  

  4.     #工作目录  

  5.     chroot /usr/local/etc/haproxy  

  6.     #日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info  

  7.     log 127.0.0.1 local5 info  

  8.     #守护进程运行  

  9.     daemon  

  10. defaults  

  11.     log global  

  12.     mode    http  

  13.     #日志格式  

  14.     option  httplog  

  15.     #日志中不记录负载均衡的心跳检测记录  

  16.     option  dontlognull  

  17.     #连接超时(毫秒)  

  18.     timeout connect 5000  

  19.     #客户端超时(毫秒)  

  20.     timeout client  50000  

  21.     #服务器超时(毫秒)  

  22.     timeout server  50000  

  23. #监控界面  

  24. listen  admin_stats  

  25.     #监控界面的访问的IP和端口  

  26.     bind  0.0.0.0:8888  

  27.     #访问协议  

  28.     mode        http  

  29.     #URI相对地址  

  30.     stats uri   /dbs  

  31.     #统计报告格式  

  32.     stats realm     Global\ statistics  

  33.     #登录帐户信息  

  34.     stats auth  admin:123456  

  35. #数据库负载均衡  

  36. listen  proxy-mysql  

  37.     #访问的IP和端口  

  38.     bind  0.0.0.0:3306  

  39.     #网络协议  

  40.     mode  tcp  

  41.     #负载均衡算法(轮询算法)  

  42.     #轮询算法:roundrobin  

  43.     #权重算法:static-rr  

  44.     #最少连接算法:leastconn  

  45.     #请求源IP算法:source  

  46.     balance  roundrobin  

  47.     #日志格式  

  48.     option  tcplog  

  49.     #在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测  

  50.     option  mysql-check user haproxy  

  51.     server  mysql-node1 172.18.0.2:3306 check weight 1 maxconn 2000  

  52.     server  mysql-node2 172.18.0.3:3306 check weight 1 maxconn 2000  

  53.     server  mysql-node3 172.18.0.4:3306 check weight 1 maxconn 2000  

  54.     server  mysql-node4 172.18.0.5:3306 check weight 1 maxconn 2000  

  55.     server  mysql-node5 172.18.0.6:3306 check weight 1 maxconn 2000  

  56.     #使用keepalive检测死链  

  57.     option  tcpka

  1. 在数据库集群中创建空密码、无权限用户 haproxy,来供 Haproxy 对 MySQL 数据库进行心跳检测

  1. # 进入容器  

  2. $ docker exec -it mysql-node1 /bin/bash  

  3. # 登录mysql  

  4. $ mysql -uroot -p123456  

  5. # 创建用户  

  6. mysql> create user 'haproxy'@'%' identified by '';

  1. 创建第 1 个 Haproxy 负载均衡服务器

$ docker run -it -d --name haproxy-node1 -p 4001:8888 -p 4002:3306 --restart always --privileged=true -v /home/apps/haproxy:/usr/local/etc/haproxy --net=net1 --ip 172.18.0.7 haproxy:2.3.13
  1. 启动 Haproxy

  1. # 进入容器  

  2. $ docker exec -it haproxy-node1 /bin/bash  

  3. # 启动haproxy  

  4. $ haproxy -f /usr/local/etc/haproxy/haproxy.cfg

4访问测试

  1. 页面访问

  • ip:4001/dbs,在配置文件中定义有用户名admin,密码:123456

94176c590ec48360498542d62bb821fa.png

  1. 数据库访问

  • 使用 Navacat 访问代理集群,端口为 4002

e0ecbe1aafa16d9d36070e5ef1be794b.png

  1. 测试 Docker 挂掉

  • 分别下线第一和第二个节点,通过访问其它节点或代理节点都能正常使用

45479da63690989393759ad330f150b5.png

5节点宕机或重启

  1. 从节点宕机后的操作

  • 如果指定的主节点没有宕机,直接启动从节点容器,数据会自动同步

  1. 主节点宕机后的操作

  • [重启用此操作] 如果主节点是最后一个离开集群的(说明数据是最新的),只要重启主节点即可,主节点的启动需要设置 safe_to_bootstrap: 1 才能启动

  1. # 修改 grastate.dat  

  2. $ vim /var/lib/docker/volumes/v1/_data/grastate.dat  

  3. # 将以下值改为1  

  4. safe_to_bootstrap: 1  

  5. # 启动主节点  

  6. $ docker start mysql-node1

  • 如果其他节点还在运行中,主节点挂掉了(说明主节点的数据已经不是最新的了),需要删除主节点容器,原来的数据卷无需删除(继续使用,避免数据丢失),然后再以从节点方式加入集群,注意加参数 "-e CLUSTER_JOIN=mysql-node2",指定可用的从节点启动

$ docker run -d --name=mysql-node1 -p 3310:3306 --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node2 -v v1:/var/lib/mysql --net=net1 --ip 172.18.0.2 pxc
  1. 另一种启动方式,删除集群容器和数据卷中的grastate.dat文件,重新创建

  • 该方案会以主节点的数据恢复,如果主节点数据不是最新的,会造成数据丢失

  1. # 移除容器  

  2. docker rm mysql-node1 mysql-node2 mysql-node3 mysql-node4 mysql-node5  

  3. # 移除数据卷中的grastate.dat文件  

  4. rm -rf /var/lib/docker/volumes/v1/_data/grastate.dat  

  5. rm -rf /var/lib/docker/volumes/v2/_data/grastate.dat  

  6. rm -rf /var/lib/docker/volumes/v3/_data/grastate.dat  

  7. rm -rf /var/lib/docker/volumes/v4/_data/grastate.dat  

  8. rm -rf /var/lib/docker/volumes/v5/_data/grastate.dat  

  9. # 按上面的方式重新创建集群容器

6参考

  • https://www.cnblogs.com/wanglei957/p/11819547.html

  • 节点宕机:https://www.cnblogs.com/wangbiaohistory/p/14638935.html

本文转载自:「 博客园 」,原文:https://tinyurl.com/yhvzn3x2 ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

24f3edd893c94207b31ee1931cbc9fc3.gif

b7bc2ec12e91a7a0410a558ada513e26.png

你可能还喜欢

ce5ae9003adac9e64b9e02dde2bd24c1.png

强势解锁 GitHub 新姿势,一键实现在线编写代码!

e14a25358075b62eac87b96cb166ff9c.png

点击上方图片,『美团|饿了么』大额外卖红包天天免费领

09f42cf80bc41cf757d8e77537bb2c54.png

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!