文章摘要:
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