Docker+PXC+Haproxy搭建高可用MySQL集群

搭建
本次搭建集群环境以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的数据并还原」这一步看是否还原成功,用工具连接数据库查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/236966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DOM是什么?

1、概述 (1)DOM代表文档对象模型,是 HTML 和 XML 文档的接口(API) (2)当浏览器第一次读取(解析)HTML文档时,会创建一个基于 HTML 文档的大对象,…

SpringBoot操作Redis缓存

SpringBoot操作Redis缓存 Redis有很多使用场景,一个使用场景就是缓存数据库的数据。Redis作为一个内存数据库,存取数据的速度比传 统的数据库快得多。使用Redis缓存数据库数据,可以减轻系统对数据库的访问压力,及加快查询效率等…

听GPT 讲Rust源代码--src/tools(15)

File: rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs 在Rust源代码中,rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs文件的作用是实现了一个能够将输入的文本映射为标记的结构。具体来说,它定义和实现了几个结构体&#xff08…

【已解决】Mysql在更新的时候,需要更新的字段是其他表查询的值,这个时候update语句怎么写

Mysql在更新的时候,需要更新的字段是其他表查询的值,这个时候update语句怎么写? 例如:我想要更新A表中的floor字段。但是这个字段的是是根据条件在B表中查询后,得到的值。 这样需求的sql语句怎么写 ? 要点&#xff…

Mysql5.7版本中,查询分组GROUP BY通过子查询中ORDER BY进行排序无效的问题解决办法

文章目录 一、场景:二、解决办法1、使用 having 来阻止合并2、足够大的limit3、子查询 一、场景: 问题描述:Mysql5.7版本中,查询分组GROUP BY通过子查询中ORDER BY进行排序无效的问题解决办法。 应用场景:一对多的关系…

数据库(三)超详细SQL语句入门 | SQL增删改查,重命名,字符操作,联合操作,聚合函数,嵌套子查询

文章目录 1 SQL表内类型2 SQL增删改语句2.1 创建表2.2 删除表2.3 表中添加属性2.4 添加新的元组信息2.5 删除表所有元组2.6 元组 3 查询语句4 重命名4.1 为什么用 5 字符操作5.1 寻找 6 生序降序7 联合操作7.1 并集Union7.2 交集 INTERSECT7.3 差集 EXCEPT7.4 对于空值补充 8 聚…

掀起全新的互联网直播风潮

随着科技的不断进步和智能手机的普及,无人直播作为一种全新的互联网直播方式,在近些年迅速崛起,并引起了广泛关注。本文将围绕手机无人直播展开探讨,探究其背后的原因以及对社会生活带来的影响。 首先,我们需要明确什…

[Angular] 笔记 5:ngClass

Angular 中的 ngClass 是什么? chatgpt 回答: 在Angular中,ngClass 是一个内置的指令,用于动态地添加或移除 HTML 元素的 CSS 类。它允许你根据条件设置一个或多个 CSS 类,可以是对象、数组或字符串。 使用方式&#…

一篇文章带你进阶CTF命令执行

以下的命令是为了方便以后做题时方便各位读者直接来这里复制使用,刚开始还请先看完这篇文章后才会懂得下面的命令 ?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-…

mysql:查看服务端没有睡眠的线程数量

使用命令show global status like Threads_running;可以查看服务端没有睡眠的线程数量。 例如:

使用React和ResizeObserver实现自适应ECharts图表

关键词 React ECharts ResizeObserver 摘要 在现代 Web 开发中,响应式布局和数据可视化是非常常见的需求。本文将介绍如何使用React、ResizeObserver和ECharts库来创建一个自适应的图表组件。 什么是ResizeObserver ResizeObserver是JavaScript的一个API&#x…

定时任务,停用用户。

1&#xff0c; <!-- 定时3.用户三个月无操作&#xff0c;停用用户 begin --> <bean id"autoStopSleepUserService" class"com.rjhc.application.sysmanage.service.impl.SysTaskScheduleServiceImpl" /> <bean id"jobDetail_…

玩转Spring状态机

说起Spring状态机&#xff0c;大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢&#xff1f;没错&#xff0c;Spring状态机就是状态模式的一种实现&#xff0c;在介绍Spring状态机之前&#xff0c;让我们来看看设计模式中的状态模式。 1. 状态模式 状态模式的定义如…

代码随想录 322. 零钱兑换

题目 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无限的。…

[Encryptedd@mailfence.com].faust 勒索病毒肆虐:如何恢复被加密的数据文件?

导言&#xff1a; 在网络安全的战场上&#xff0c;[backupsairmail.cc].faust [Deciphermailfence.com].faust[Encrypteddmailfence.com].faust[support2022cock.li].faust [tsai.shenmailfence.com].faust勒索病毒是一种极具破坏性的恶意软件。本文91数据恢复将深入介绍该病毒…

Docker仓库

官方docker仓库使用 网址&#xff1a;https://hub.docker.com 每个注册用户都可以上传和管理自己的镜像 用户登录 上传镜像前需要登陆&#xff0c;登陆后生成~/.docker/config.json文件保存验证信息 docker login 给本地镜像打标签 上传本地镜像前必须先给上传的镜像用do…

【krita】实时绘画 入门到精通 海报+电商+装修+人物

安装插件 首先打开comfyUI&#xff0c;再打开krita&#xff0c;出现问题提示&#xff0c; 打开 cd custom_nodes 输入命令 安装控件 git clone https://github.com/Acly/comfyui-tooling-nodes.git krita基础设置 设置模型 设置lora &#xff08;可设置lora强度 增加更多…

◢Django md5加密与中间件middleware

utils文件夹是重新建立的&#xff08;与migrations同级&#xff09;&#xff0c;该文件夹下主要存放工具&#xff0c;就像static文件夹下只存放静态文件一样 加密 在utils文件夹下建立encrypt.py文件 from django.conf import settings import hashlib def md5(data_string)…

Airtest1.2.7新增断言API介绍

1. 前言 1.2.7版本的Airtest中&#xff0c;一个很重要的功能是 新增了非常丰富的断言API &#xff0c;今天我们就来详细看一下Airtest都给我们提供了哪些断言语句。 2. 旧版Airtest提供的断言语句 先回顾下&#xff0c;旧版Airtest一直以来&#xff0c;都只给我们提供了2种断言…

Samtec信号完整性 这家连接器的设计很优秀!

【Samtec技术研发&#xff1a;信号完整性设计】 1. 什么是信号完整性&#xff1f; 信号完整性需要在整个系统和组件设计过程中加以考虑。与过去不同的是&#xff0c;互连不再是事后考虑的问题。随着上升时间的缩短和时钟频率的提高&#xff0c;曾经被认为是电气透明的连接器和…