文章摘要:
DBLE 是一款企业级的开源分布式中间件,江湖人送外号 “MyCat Plus”。为了分担 DBLE 的集群管理压力同时避免单点故障,需要为 DBLE 寻找一个负载均衡方案。我们找来了 Lvs+Keepalived 为 DBLE 实现负载均衡。本章概要:
一、负载均衡环境介绍
1.部署架构
2.架构软件版本
二、环境搭建
1.安装 DBLE
2.安装 MySQL
3.安装 Lvs+Keepalived
三、负载均衡实验
1.场景一:DBLE被停掉到恢复过程中的负载均衡
2.场景二:DBLE从网络断开到恢复的过程中的负载均衡
3.场景三:整套环境在压力测试下负载均衡的稳定性
四、环境搭建过程中可能遇到的问题
一、负载均衡环境介绍
1.部署架构
外部对虚拟IP地址发出请求,负载均衡层一主一备避免单点故障,然后由 Lvs+Keepalived 实现 DBLE 层的负载均衡,DBLE 层用指定规则将数据在 MySQL 集群中分片存储。
2.架构软件版本
操作系统:Ubuntu 17.10
内核:Linux R820-08 4.13.0-32-generic x86_64 GNU/Linux
负载均衡:ipvsadm:v1.2.1
Keepalived:v1.3.2 (06/17,2017)
数据库:MySQL 5.7.13
压力测试工具:sysbench v1.0
DBLE:5.6.29-dble-2.19.01.0
二、环境搭建
1.安装 DBLE(2台需安装 DBLE 机器上均执行)
下载安装包:
shell>wget -c https://github.com/actiontech/dble/releases/download/2.19.01.0%2Ftag/actiontech-dble-2.19.01.0.tar.gz
解压安装包:
shell>tar xvf actiontech-dble-2.19.01.0.tar.gz
DBLE配置说明:
库名:lvs_test ;表名:sbtest1;分片数:2;规则:简单hash
每台数据库对应1个分片,具体配置方式可参考《开源分布式中间件DBLE快速入门指南》
启动DBLE:
shell>$install/bin/dble start
2.安装 MySQL(2台需安装 MySQL 机器上均执行)
创建DBLE操作MySQL的账户action,并授权远程登录。
3.安装 Lvs+Keepalived(2台需安装负载均衡机器上均执行)
安装Keepalived和ipsadm:
shell>apt install -y ipvsadm keepalived
编辑Keepalived配置文件(master和slave做区分)
shell>vi /etc/keepalived/keepalived.conf
其中重要配置说明:
本架构采用的是主备架构模式,Keepalived的配置包含master跟slave两个部分。
vrrp_instance模块用来定义虚拟路由器,其中部分参数说明如下:
– state:服务器的初始状态,指定为master或slave,但实际master的选举是按照下面配置的优先级来定,优先级高的为master
– interface:实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的
– virtual router id:相同的VRID为一个组
– priority:设置本节点的优先级,优先级高的为master
– advert int:检查的时间间隔
– virtual_ipaddress:虚拟ip地址
virtual_server模块,是Lvs+Keepalived中Lvs部分的配置,指定real server所属的virtual server: VIP:Vport
– delay_loop:服务轮询的时间隔
– lb_algo:LVS调度算法,本次测试使用的是rr
– lb_kind:LVS集群模式,本次测试使用的是DR
– protocol:健康检查方式
– real_server
– weight :每台的权重
– HTTP_GET:健康检查方式
– connect_timeout:连接超时时间
– nb_get_retry:重连次数
– delay_before_retry:重连间隔
keepalived.conf(master)
global_defs {
router_id LVS_MASTER
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eno3
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.186.17.150
}
}
virtual_server 10.186.17.150 8066 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.186.17.105 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
real_server 10.186.17.107 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
}
keepalived.conf(slave)
global_defs {
router_id LVS_SLAVE
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface eno3
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.186.17.150
}
}
virtual_server 10.186.17.150 8066 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.186.17.105 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
real_server 10.186.17.107 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
}
启动Keepalived:
shell>systemctl start keepalived
检测Keepalived状态:
shell>systemctl status keepalived
master状态
keepalived.service - Keepalive Daemon (LVS and VRRP)
Loaded: loaded (/lib/systemd/system/keepalived.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-03-11 15:17:10 CST; 20h ago
Process: 13289 ExecStart=/usr/sbin/keepalived $DAEMON_ARGS (code=exited, status=0/SUCCESS)
Main PID: 13300 (keepalived)
Tasks: 3 (limit: 14745)
Memory: 3.7M
CPU: 11.980s
CGroup: /system.slice/keepalived.service
├─13300 /usr/sbin/keepalived
├─13304 /usr/sbin/keepalived
└─13306 /usr/sbin/keepalived
Mar 11 15:17:16 R820-02 Keepalived_healthcheckers[13304]: Removing service [10.186.17.107]:8066 from VS [10.186.17.150]:8066
Mar 11 15:17:19 R820-02 Keepalived_healthcheckers[13304]: TCP connection to [10.186.17.105]:8066 failed.
Mar 11 15:17:19 R820-02 Keepalived_healthcheckers[13304]: Check on service [10.186.17.105]:8066 failed after 1 retry.
Mar 11 15:17:19 R820-02 Keepalived_healthcheckers[13304]: Removing service [10.186.17.105]:8066 from VS [10.186.17.150]:8066
Mar 11 15:17:19 R820-02 Keepalived_healthcheckers[13304]: Lost quorum 1-0=1 > 0 for VS [10.186.17.150]:8066
Mar 11 15:28:55 R820-02 Keepalived_healthcheckers[13304]: TCP connection to [10.186.17.107]:8066 success.
Mar 11 15:28:55 R820-02 Keepalived_healthcheckers[13304]: Adding service [10.186.17.107]:8066 to VS [10.186.17.150]:8066
Mar 11 15:28:55 R820-02 Keepalived_healthcheckers[13304]: Gained quorum 1+0=1 <= 1 for VS [10.186.17.150]:8066
Mar 11 15:40:58 R820-02 Keepalived_healthcheckers[13304]: TCP connection to [10.186.17.105]:8066 success.
Mar 11 15:40:58 R820-02 Keepalived_healthcheckers[13304]: Adding service [10.186.17.105]:8066 to VS [10.186.17.150]:8066
slave状态
keepalived.service - Keepalive Daemon (LVS and VRRP)
Loaded: loaded (/lib/systemd/system/keepalived.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-03-11 16:13:35 CST; 19h ago
Process: 38895 ExecStart=/usr/sbin/keepalived $DAEMON_ARGS (code=exited, status=0/SUCCESS)
Main PID: 38909 (keepalived)
Tasks: 3 (limit: 14745)
Memory: 3.5M
CPU: 11.928s
CGroup: /system.slice/keepalived.service
├─38909 /usr/sbin/keepalived
├─38910 /usr/sbin/keepalived
└─38912 /usr/sbin/keepalived
Mar 11 16:13:35 R820-01 Keepalived_vrrp[38912]: Registering Kernel netlink command channel
Mar 11 16:13:35 R820-01 Keepalived_healthcheckers[38910]: Unknown keyword 'nb_get_retry'
Mar 11 16:13:35 R820-01 Keepalived_healthcheckers[38910]: Unknown keyword 'nb_get_retry'
Mar 11 16:13:35 R820-01 Keepalived_vrrp[38912]: Registering gratuitous ARP shared channel
Mar 11 16:13:35 R820-01 Keepalived_vrrp[38912]: Opening file '/etc/keepalived/keepalived.conf'.
Mar 11 16:13:35 R820-01 Keepalived_healthcheckers[38910]: Using LinkWatch kernel netlink reflector...
Mar 11 16:13:35 R820-01 Keepalived_healthcheckers[38910]: Activating healthchecker for service [10.186.17.105]:8066
Mar 11 16:13:35 R820-01 Keepalived_healthcheckers[38910]: Activating healthchecker for service [10.186.17.107]:8066
Mar 11 16:13:35 R820-01 Keepalived_vrrp[38912]: Using LinkWatch kernel netlink reflector...
Mar 11 16:13:35 R820-01 Keepalived_vrrp[38912]: VRRP_Instance(VI_1) Entering BACKUP STATE
配置real server(在两台DBLE环境中均执行):
shell>/sbin/ifconfig eno3:0 10.186.17.150 broadcast 10.186.17.150 netmask 255.255.255.255 up
shell>/sbin/route add -host 10.186.17.150 dev eno3:0
shell>sysctl -w net.ipv4.conf.all.arp_ignore=1
shell>sysctl -w net.ipv4.conf.all.arp_announce=2
shell>sysctl -w net.ipv4.conf.lo.arp_ignore=1
shell>sysctl -w net.ipv4.conf.lo.arp_announce=2
shell>sysctl -p
验证:
在负载均衡服务器上执行:ipvsadm -ln
修改timeout值:
查看默认超时时间
shell>ipvsadm -L --timeout
说明:一条TCP的连接经过Lvs后,Lvs会把记录保存15分钟,容易对测试过程中的观测过程造成不便。
调整超时时间
shell>ipvsadm --set 1 2 1
三、负载均衡实验
数据准备:
用SysBench用具的插入数据脚本为两台MySQL的lvs_test库创建数据表并插入数据。测试数据一共10000条,根据分片数和规则导致数据各5000条。
shell>cd $sysbench/bin
//进入sysbench安装目录
shell>./sysbench --mysql-db=lvs_test --db-driver=mysql --mysql-host=10.186.17.150 \
--mysql-port=8066 --mysql-table-engine=innodb --mysql-user=action \
--oltp_auto_inc=off --mysql-password=action --test=../db/insert.lua \
--oltp_tables_count=1 --oltp-table-size=10000 prepare
1.场景一:DBLE被停掉到恢复过程中的负载均衡
步骤一:使用sysbench对vip加压
shell>./sysbench --mysql-db=lvs_test --mysql-host=10.186.17.150 \
--mysql-port=8066 --mysql-table-engine=innodb --mysql-user=action \
--mysql-password=action --test=../db/select.lua --oltp_tables_count=1 \
--oltp-table-size=10000 --num-threads=200 --report-interval=1 \
--default-charset=utf8 --max-time=600000 --max-requests=0 \
--percentile=95 --mysql-ignore-errors=2013 run
步骤二:观测负载均衡上连接的分配情况
shell>ipvsadm -ln
结论:存活连接各100个,符合比重1:1的预期
步骤三:停止DBLE1,观测负载均衡上连接的情况
进入DBLE目录执行:
shell>$install/bin/dble stop
检测DBLE状态:
shell>$install/bin/dble status
负载均衡情况:
结论:连接异常的DBLE1被踢出,所有的流量全部打到DBLE2上
步骤四:恢复DBLE1,观测未新建连接情况下(SysBench为长连接)负载均衡上连接的情况
进入DBLE目录执行:
shell>$install/bin/dble start
检测DBLE状态:
shell>$install/bin/dble status
负载均衡情况:
结论:DBLE1被重新加进来,但原有的存活的长连接不会被转移到DBLE1上
步骤五:关闭已有长连接,新建连接,查看负载均衡上连接的情况
结束原有的SysBench压力后,重复步骤一
负载均衡情况:
结论:该场景中DBLE实现负载均衡。
2.场景二: DBLE从网络断开到恢复的过程中的负载均衡**
步骤一:使用SysBench对vip加压
sysbench命令
shell>./sysbench --mysql-db=lvs_test --mysql-host=10.186.17.150 \
--mysql-port=8066 --mysql-table-engine=innodb --mysql-user=action \
--mysql-password=action --test=../db/select.lua --oltp_tables_count=1 \
--oltp-table-size=10000 --num-threads=200 --report-interval=1 \
--default-charset=utf8 --max-time=600000 --max-requests=0 \
--percentile=95 --mysql-ignore-errors=2013 run
步骤二:观测负载均衡上连接的分配情况
命令:ipvsadm -ln
结论:存活连接各100个,符合比重1:1的预期。
步骤三:断开vip到DBLE1的网络,观测负载均衡上连接的情况
进入DBLE1环境执行:
shell>iptables -A INPUT -p tcp --dport 8066 -j DROP
负载均衡情况:
结论:连接异常的DBLE1被踢出,所有的流量全部打到DBALE2上。
步骤四:恢复vip到DBLE1的网络,观测未新建连接情况下(sysbench为长连接)负载均衡上连接的情况
进入DBLE1环境执行:
shell>iptables -D INPUT -p tcp --dport 8066 -j DROP
负载均衡情况:
结论:DBLE1被重新加进来,但原有存活的长连接不会被转移到DBLE1上。
步骤五:关闭已有长连接,新建连接,查看负载均衡上连接的情况
结束原有的sysbench压力后,重复步骤一
负载均衡情况:
结论:该场景中DBLE实现负载均衡。
3.场景三:整套环境在压力测试下负载均衡的稳定性
稳定性sysbench命令
shell>nohup ./sysbench --mysql-db=lvs_test --mysql-host=10.186.17.150 \
--mysql-port=8066 --mysql-table-engine=innodb --mysql-user=action \
--mysql-password=action --test=../db/select.lua --oltp_tables_count=1 \
--oltp-table-size=10000 --num-threads=1024 --oltp-read-only=off \
--report-interval=1 --default-charset=utf8 --max-time=950400 \
--max-requests=0 --percentile=95 run &
测试结果:
结论:11天的稳定性测试没有出现异常, Lvs+Keepalived完成了对DBLE的负载均衡实践,适应性及稳定性得到了验证。
总结: Lvs+Keepalived实现了DBLE负载均衡方案,压力测试中配合过程无异常,组件之间适应性好,整体架构稳定。
四、环境搭建过程中可能遇到的问题
1.Keepalived slave报错
原因:缺少包:libipset.so.3
解决方案:apt install ipset
2.注意防火墙和selinux可能引起的网络连通性的问题
开源分布式中间件DBLE
社区官网:https://opensource.actionsky.com/
GitHub主页:https://github.com/actiontech/dble
技术交流群:669663113
开源数据传输中间件DTLE
社区官网:https://opensource.actionsky.com/
GitHub主页:https://github.com/actiontech/dtle
技术交流群:852990221