一、负载均衡中间件的选择
上一篇成功搭建了数据库集群,但在pxc数据库集群中,任何一个节点都是可以读写的。
如果pxc集群上线后,不应该把所有的请求都发送给一个节点,所有节点都应该参与数据请求的处理。
如果想要实现将请求均匀的发送给每个节点,就需要实现负载均衡。
1.1 为什么要实现负载均衡?
如果不上线负载均衡,应用服务器将所有请求都发送给一个pxc节点,这个节点压力特别高,就容易出现崩溃:
因此在结构上就需要进行调整,想要实现需要引入Haproxy技术,Haproxy是一个老牌的中间件产品,Haproxy不是数据库,它只是一个转发器而已。使用Haproxy做负载均衡,请求被均匀发送给每个节点,使单节点负载降低,提高性能:
1.2 为什么不使用Nginx来实现?
我们都知道Nginx的重要特点就是可以用来实现负载均衡,这里数据库节点的负载均衡为什么不使用Nginx实现?
对比几款负载均衡中间件,可以发现:
Nginx对于Http协议的负载均衡支持非常好,但是对于TCP\IP协议的支持并不久。
没有长久的考验,不适合贸然在数据库集群中来使用Nginx来实现负载均衡。
另外,还有Apache是不支持TCP\IP协议的,
以及,LVS也支持TCP/IP协议的负载均衡,甚至性能更好,但是它不支持在虚拟机上安装,因此也无法在docker容器中去使用。
二、负载均衡的实现
2.1 拉取haproxy远程镜像
docker仓库中已有haproxy的镜像,下载即可:
拉取haproxy镜像 docker pull haproxy
查看镜像是否拉取成功 docker images
2.2 创建haproxy的配置文件
2.2.1 配置文件部分内容说明
部分重点配置参数说明(这里只关注和pxc负载均衡有关的部分):
#数据库负载均衡
listen proxy-mysql
#访问的IP和端口,表示任何ip地址都可以访问这个3306的端口。假如有有应用程序向3306端口发送数据库请求,它就会把请求发送给具体的pxc实例
bind 0.0.0.0:3306
#网络协议
mode tcp
#负载均衡算法(轮询算法),请求的转发算法。
(由于我pxc容器中的mysql数据库硬件配置都是相同的,因此不需要采用权重算法,当硬件配置不同时才用权重算法给实例分配不同的权重。这里开启的是roundrobin,即轮询算法。)
#轮询算法:roundrobin
#权重算法:static-rr
#最少连接算法:leastconn
#请求源IP算法:source
balance roundrobin
#日志的格式
option tcplog
#在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测。
option mysql-check user haproxy
#★★★配置具体的负载均衡数据库节点★★★
#[server] [自定义一个配置信息名] [数据库节点的ip:容器的端口而不是宿主机的端口] [check(指发送心跳检测)] [未配置轮询不会生效的轮询权重] [最大连接数设置为2000 可按需自定义]
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
2.2.2 完整的配置文件
配置文件如下,可以直接复制到haproxy.cfg中使用。(关于haproxy配置文件的详细可以参考:https://zhangge.net/5125.html )
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
2.2.3 创建haproxy的配置文件
注意先不要去创建haproxy的容器,haproxy的镜像中是不包含配置文件的,因此需先创建其配置文件。
创建haproxy的配置文件,若目录不存在需先创建目录 touch /home/soft/haproxy/haproxy.cfg
将上面贴出的配置文件内容复制进去并保存。
2.3 创建Haproxy容器
创建Haproxy容器:
docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy
参数说明:
-p 4001:8888 将Haproxy提供的监控界面服务端口8888映射到宿主机的4001端口
-p 4002:3306 将Haproxy提供的数据库负载均衡的服务端口3306映射到宿主机的4002端口
-v /home/soft/haproxy:/usr/local/etc/haproxy 将宿主机的/home/soft/haproxy目录映射到容器的/usr/local/etc/haproxy目录。将来在宿主机的/home/soft/haproxy中放入配置文件,在相映射的容器目录中就可以使用了。
--name h1 给容器起名,为了保证Haproxy的高可用,将来也会启动多个Haproxy容器实例
--privileged 配置权限
--net=net1 使用的网段,数据库实例使用的都是net1网段,需和数据库实例使用的网段保持一致
--ip 172.18.0.7 手动分配的ip地址,如不设置,docker虚拟机也会给其分配一个ip地址
haproxy docker run使用的镜像名
运行结果如图:
2.4 在haproxy容器中启动haproxy实例
2.4.1 启动haproxy实例
由于容器是使用-d做后台运行的,因此之后还需要进入后台运行的容器,把haproxy中间件启动起来。
进入后台运行的容器:
docker exec -it h1 bash
指定配置文件启动haproxy实例:
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
运行结果如图:
2.4.2 创建心跳检测的用户账号
在之前的haproxy配置中配置了一个用于心跳检测的账号haproxy。
我们需要在mysql数据库实例上创建一个叫haproxy的账号,因为haproxy中间件要用这个账号登录数据库发送心跳检测:
2.4.5 查看haproxy监控界面
打开浏览器,输入宿主机ip:4001/dbs,即可查看haproxy的监控界面:
可以看到,其中五个数据库节点背景色都为绿,status一项都是UP,也就是说都是稳定运行中。
尝试停止其中一台实例node2,运行命令:docker stop node2
刷新再次查看监控界面,可以在监控界面发现node2已经显示未正常运行:
三、查看haproxy负载均衡功能是否生效
新建连接h1,ip为宿主机ip,端口为宿主机的端口(Haproxy服务端口3306映射到宿主机的端口4002,填写mysql实例的用户名和密码。haproxy的库其实并不会保存数据,只是做请求分发。
打开连接h1,可以看到之前在pxc的mysql实例中创建的test库和student表。现在对其新增一条数据Jack:
去pxc的node1节点对应的数据库DB1查看,可以发现jack这条数据已经同步进来:
再查看DB3,也已经存在这条数据了。说明haproxy确实正常运行了: