LVS + Keepalived + MyCAT搭建高可用负载均衡集群
LVS + Keepalived + MyCAT搭建高可用负载均衡集群
LVS + Keepalived介绍
LVS
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。目前有三种IP负载均衡技术(VS/NAT、VS/TUN和VS/DR),十种调度算法(rrr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq)。
LVS集群采用IP负载均衡技术,属于IP层的交换(L4), 具有很好的吞吐率。调度器分析客户端到服务器的IP报头信息,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器,LVS集群系统的通用结构如图1.1所示,主要包含四大部分:
负载调度器(load balancer),它是整个集群对外面的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务是来自一个IP地址上的。当客户请求到达时,调度器只根据负载情况从服务器池中选出一个服务器,将该请求转发到选出的服务器,并记录这个调度;当这个请求的其他报文到达,也会被转发到前面选出的服务器。因为所有的操作都是在操作系统核心空间中将完成的,它的调度开销很小,所以具有很高的吞吐率。
服务器池(server pool),是一组真正执行客户请求的服务器,执行的任务有WEB、MAIL、FTP和DNS等。服务器池的结点数目是可变的,当整个系统收到的负载超过目前所有结点的处理能力时,可以在服务器池中增加服务器来满足不断增长的请求负载。对大多数网络服务来说,结点与结点间不存在很强的相关性,所以整个系统的性能可以随着服务器池的结点数目增加而线性增长。
后端存储(backend storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。
Graphic Monitor是为系统管理员提供整个集群系统的监视器,它可以监视系统中每个结点的状况。
Keepalvied
Keepalived在这里主要用作RealServer的健康状态检查以及Master主机和BackUP主机之间failover的实现
Keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。
Layer3,4&5工作在IP/TCP协议栈的IP层,TCP层,及应用层,原理分别如下:Layer3:Keepalived使用Layer3的方式工作式时,Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包(既我们平时用的Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。在本文中将采用这种方式。Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP端口的状态来决定服务器工作正常与否。
如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。Layer5:Layer5就是工作在具体的应用层了,比Layer3,Layer4要复杂一点,在网络上占用的带宽也要大一些。Keepalived将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则Keepalived将把服务器从服务器群中剔除。
搭建基于LVS+Keepalived的MyCAT高可用负载均衡集群,其中,LVS实现MyCAT的负载均衡,但是,简单的LVS不能监控后端节点是否健康,它只是基于具体的调度算法对后端服务节点进行访问。同时,单一的LVS又存在单点故障的风险。在这里,引进了Keepalived,可以实现以下几个功能:
1. 检测后端节点是否健康。
2. 实现LVS本身的高可用。
配置环境:
角色 主机IP 主机名 操作系统版本 软件版本
VIP 192.168.244.10
LVS-DR-Master 192.168.244.146 keepalived01 CentOS7.1 Keepalived v1.2.13,LVS 1.2.1
LVS-DR-Backup 192.168.244.147 keepalived02 CentOS7.1 Keepalived v1.2.13,LVS 1.2.1
mycat-Realserver 192.168.244.148 mycat01 CentOS7.1 mycat v1.5
mycat-Realserver 192.168.244.149 mycat02 CentOS7.1 mycat v1.5
一、安装keepalived和ipvsadm
注意:ipvsadm并不是Lvs,它只是Lvs的配置工具,因Lvs在3.10(CentOS7.1的内核版本)的内核中是默认支持的。所以在这里就不需要重新安装。
为了方便起见,在这里我们使用yum的安装方式
分别在keepalived01和keepalived02两台主机上安装keepalived和ipvsadm
[root@localhost ~]# yum -y install ipvsadm keepalived
除了这种简易方式外,也可直接编译官方的源码包。
源码包安装LVS
[root@localhost ~]# yum -y install libnl* libnl libnl-devel popt* popt-static popt-devel
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
ln -sv /usr/src/kernels/`uname -r`/ /usr/src/kernels/
tar -zxvf ipvsadm-1.26.tar.gz && rm -rf ipvsadm-1.26.tar.gz
cd ipvsadm-1.26
make -j 4
make install
cd .. && rm -rf ipvsadm-1.26
源码包安装Keepalived
[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel libnfnetlink-devel kernel-devel
wget http://www.keepalived.org/software/keepalived-1.3.5.tar.gz
tar -zxv -f keepalived-1.3.5.tar.gz && rm -rf keepalived-1.3.5.tar.gz
cd keepalived-1.3.5
./configure --sysconf=/etc --with-kernel-dir=/usr/src/kernels/`uname -r`/ && make -j 4 && make install
cp -v ~/keepalived-1.3.5/keepalived/etc/init.d/keepalived /etc/init.d/
ln -sv /usr/local/sbin/keepalived /bin/keepalived
cd .. && rm -rf keepalived-1.3.5
RHEL 5.4下部署LVS(DR)+Keepalived实现高性能高可用负载均衡安装步骤可参考:http://www.linuxidc.com/Linux/2012-05/61117.htm
二、配置Keepalived
keepalived01,即LVS-DR-Master上,其配置如下:
[root@keepalived01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email]acassen@firewall.loc[/email] #设置报警邮件地址,可以设置多个,每行一个。
[email]failover@firewall.loc[/email] #需开启本机的sendmail服务
[email]sysadmin@firewall.loc[/email]
}
notification_email_from [email]Alexandre.Cassen@firewall.loc[/email] #设置邮件的发送地址
smtp_server 127.0.0.1 #设置smtp server地址
smtp_connect_timeout 30 #设置连接smtp server的超时时间
router_id LVS_DEVEL #表示运行keepalived服务器的一个标识。发邮件时显示在邮件主题的信息
}
vrrp_instance VI_1 {
state MASTER #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器
interface eno16777736 #指定HA监测网络的接口
virtual_router_id 51 #虚拟路由标识,这个标识是一个数字,同一个vrrp实例使用唯一的标识。即同一vrrp_instance下,MASTER和BACKUP必须是一致的
priority 100 #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级
advert_int 1 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置验证类型和密码
auth_type PASS #设置验证类型,主要有PASS和AH两种
auth_pass 1111 #设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
}
virtual_ipaddress { #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
192.168.244.10
}
}
virtual_server 192.168.244.10 8066 { #设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
delay_loop 6 #设置运行情况检查时间,单位是秒
lb_algo rr #设置负载调度算法,这里设置为rr,即轮询算法
lb_kind DR #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
nat_mask 255.255.255.0
persistence_timeout 50 #会话保持时间,单位是秒。这个选项对动态网页是非常有用的,为集群系统中的session共享提供了一个很好的解决方案。
#有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。
#需要注意的是,这个会话保持时间是最大无响应超时时间,也就是说,用户在操作动态页面时,如果50秒内没有执行任何操作
#那么接下来的操作会被分发到另外的节点,但是如果用户一直在操作动态页面,则不受50秒的时间限制
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 192.168.244.148 8066 { #配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开
weight 1 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小可以为不同性能的服务器
#分配不同的负载,可以为性能高的服务器设置较高的权值,而为性能较低的服务器设置相对较低的权值,这样才能合理地利用和分配系统资源
TCP_CHECK { #realserver的状态检测设置部分,单位是秒
connect_timeout 3 #表示3秒无响应超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
connect_port 8066
}
}
real_server 192.168.244.149 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
}
将该文件scp到keepalived02上,修改如下:
! Configuration File for keepalived
global_defs {
notification_email {
[email]acassen@firewall.loc[/email]
[email]failover@firewall.loc[/email]
[email]sysadmin@firewall.loc[/email]
}
notification_email_from [email]Alexandre.Cassen@firewall.loc[/email]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP #将state从MASTER改为BACKUP
interface eno16777736
virtual_router_id 51
priority 99 #修改优先级
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.244.10
}
}
virtual_server 192.168.244.10 8066 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 192.168.244.148 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
real_server 192.168.244.149 8066 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
}
在上面这两个配置文件中,有一个地方尤其需要注意,即interface,网上的相关部署文档都是eth0,在CentOS7之前,网络接口的确都是eth0,但在CentOS7中,该接口为eno16777736。所以需要根据生产实际情况进行相应的修改。
三、安装,配置,启动MyCAT
分别在mycat01和mycat02两台主机上部署MyCAT
MyCAT是MySQL中间件,前身是阿里大名鼎鼎的Cobar,Cobar在开源了一段时间后,不了了之。于是MyCAT扛起了这面大旗,在大数据时代,其重要性愈发彰显。这篇文章主要是MyCAT的入门部署。
1、安装java
因Mycat是用java开发的,所以需要在实验环境下安装java,官方建议jdk1.7及以上版本
Java Oracle官方下载地址为:
下载最新版本1.8.0_131
wget http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz
tar zxvf jdk-8u131-linux-x64.tar.gz -C /usr/local/ && rm -rf jdk-8u131-linux-x64.tar.gz
cat >> /etc/profile <
Query OK, 1 row affected (0.00 sec)
mysql> create database db2;
Query OK, 1 row affected (0.00 sec)
mysql> create database db3;
Query OK, 1 row affected (0.00 sec)
启动mycat服务
# cd /usr/local/mycat/bin/
# ./mycat start
Starting Mycat-server...
查看mycat服务是否启动
# ps -ef |grep mycat
root 9640 7257 0 22:47 pts/3 00:00:00 grep --color=auto mycat
并没有启动
查看日志
# cd /usr/local/mycat/logs/
# cat wrapper.log
STATUS | wrapper | 2016/01/07 22:44:23 | --> Wrapper Started as Daemon
STATUS | wrapper | 2016/01/07 22:44:23 | Launching a JVM...
ERROR | wrapper | 2016/01/07 22:44:25 | JVM exited while loading the application.
INFO | jvm 1 | 2016/01/07 22:44:25 | Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: MySQL-Server1: MySQL-Server1: Name or service not known
STATUS | wrapper | 2016/01/07 22:44:29 | Launching a JVM...
ERROR | wrapper | 2016/01/07 22:44:29 | JVM exited while loading the application.
INFO | jvm 2 | 2016/01/07 22:44:29 | Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: MySQL-Server1: MySQL-Server1: Name or service not known
STATUS | wrapper | 2016/01/07 22:44:34 | Launching a JVM...
ERROR | wrapper | 2016/01/07 22:44:34 | JVM exited while loading the application.
INFO | jvm 3 | 2016/01/07 22:44:34 | Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: MySQL-Server1: MySQL-Server1: Name or service not known
STATUS | wrapper | 2016/01/07 22:44:38 | Launching a JVM...
ERROR | wrapper | 2016/01/07 22:44:38 | JVM exited while loading the application.
INFO | jvm 4 | 2016/01/07 22:44:38 | Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: MySQL-Server1: MySQL-Server1: Name or service not known
STATUS | wrapper | 2016/01/07 22:44:42 | Launching a JVM...
ERROR | wrapper | 2016/01/07 22:44:43 | JVM exited while loading the application.
INFO | jvm 5 | 2016/01/07 22:44:43 | Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: MySQL-Server1: MySQL-Server1: Name or service not known
FATAL | wrapper | 2016/01/07 22:44:43 | There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up.
FATAL | wrapper | 2016/01/07 22:44:43 | There may be a configuration problem: please check the logs.
STATUS | wrapper | 2016/01/07 22:44:43 | <-- Wrapper Stopped
根据报错信息,怀疑主机名没有绑定
修改hosts文件,绑定主机名
# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.244.144 MySQL-Server1
重新启动mycat服务
# cd /usr/local/mycat/bin/
# ./mycat start
# ps -ef |grep mycat
root 10725 1 0 22:54 ? 00:00:00 /usr/local/mycat/bin/./wrapper-linux-x86-64 /usr/local/mycat/conf/wrapper.conf wrapper.syslog.ident=mycat wrapper.pidfile=/usr/local/mycat/logs/mycat.pid wrapper.daemonize=TRUE wrapper.lockfile=/var/lock/subsys/mycat
root 10881 7257 0 22:55 pts/3 00:00:00 grep --color=auto mycat
下面以Travelrecord为例,来进行插入,查询,路由分析等基本操作。
首先利用mycat连接mysql数据库
# mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
其中8066是mycat的监听端口,类似于mysql的3306端口,其中-u,-p,-h分别是用户名,密码和主机,-D是连接的逻辑库。
至于为什么是这些,这个跟配置文件有关。
红色部分表明连接的是mycat。
创建Travelrecord表
create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
插入数据
mysql> insert into travelrecord(id,user_id,traveldate,fee,days) values(1,'Victor',20160101,100,10);
Query OK, 1 row affected (0.00 sec)
mysql> insert into travelrecord(id,user_id,traveldate,fee,days) values(5000001,'Job',20160102,100,10);
Query OK, 1 row affected (0.00 sec)
mysql> insert into travelrecord(id,user_id,traveldate,fee,days) values(10000001,'Slow',20160103,100,10);
Query OK, 1 row affected (0.00 sec)
至于ID为什么取三个值,这个与conf目录下autopartition-long.txt的定义有关,这个文件主要定义auto-sharding-long的规则。
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
主要是测试在id取不同区间的值时,分片的效果。
下面来看看分片的效果
mysql> select * from db1.travelrecord;
+----+---------+------------+------+------+
| id | user_id | traveldate | fee | days |
+----+---------+------------+------+------+
| 1 | Victor | 2016-01-01 | 100 | 10 |
+----+---------+------------+------+------+
1 row in set (0.00 sec)
mysql> select * from db2.travelrecord;
+---------+---------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------+------------+------+------+
| 5000001 | Job | 2016-01-02 | 100 | 10 |
+---------+---------+------------+------+------+
1 row in set (0.00 sec)
mysql> select * from db3.travelrecord;
+----------+---------+------------+------+------+
| id | user_id | traveldate | fee | days |
+----------+---------+------------+------+------+
| 10000001 | Slow | 2016-01-03 | 100 | 10 |
+----------+---------+------------+------+------+
1 row in set (0.00 sec)
果然是分配到三个不同的节点上了。
如果想看MyCAT具体会将数据分配到哪个节点上,可通过路由分析。
语法其实蛮简单,就是SQL语句前加上explain语句。
下面根据explain命令查看create语句和insert语句具体会分配到哪些Datanode上。
mysql> explain create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
+-----------+-----------------------------------------------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+-----------------------------------------------------------------------------------------------------------------------+
| dn1 | create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int) |
| dn2 | create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int) |
| dn3 | create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int) |
+-----------+-----------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> explain insert into travelrecord(id,user_id,traveldate,fee,days) values(1,'Victor',20160101,100,10);
+-----------+----------------------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+----------------------------------------------------------------------------------------------+
| dn1 | insert into travelrecord(id,user_id,traveldate,fee,days) values(1,'Victor',20160101,100,10) |
+-----------+----------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> explain insert into travelrecord(id,user_id,traveldate,fee,days) values(5000001,'Job',20160102,100,10);
+-----------+-------------------------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------------------------------------------------------------------+
| dn2 | insert into travelrecord(id,user_id,traveldate,fee,days) values(5000001,'Job',20160102,100,10) |
+-----------+-------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> explain insert into travelrecord(id,user_id,traveldate,fee,days) values(10000001,'Slow',20160103,100,10);
+-----------+---------------------------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+---------------------------------------------------------------------------------------------------+
| dn3 | insert into travelrecord(id,user_id,traveldate,fee,days) values(10000001,'Slow',20160103,100,10) |
+-----------+---------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
总结:
关于MyCAT的配置其实是蛮简单的,最主要的是熟悉各配置文件的规则。以上用户名,密码,如何分库,都是在配置文件中定义的,后续,有时间再一一详表。
关于配置文件,conf目录下主要以下三个需要熟悉。
server.xml是Mycat服务器参数调整和用户授权的配置文件
schema.xml是逻辑库定义和表以及分片定义的配置文件
rule.xml是分片规则的配置文件
注意:为了便于观察后续MyCAT负载均衡的效果,MyCAT的配置文件并没有进行修改,均是指向本地的MySQL实例。
四、在MyCAT服务器上为lo:0绑定VIP地址、抑制ARP广播
分别在mycat01和mycat02两台主机上执行以下脚本。
[root@mycat01 ~]# cat realserver.sh
#!/bin/bash
#description: Config realserver
VIP=192.168.244.10
. /etc/rc.d/init.d/functions
case "$1" in
start)
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255
/sbin/route add -host $VIP dev lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo "RealServer Start OK"
;;
stop)
/sbin/ifconfig lo:0 down
/sbin/route del $VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
[root@mycat01 ~]# sh realserver.sh start
[root@mycat02 ~]# sh realserver.sh start
执行ip addr查看VIP是否绑定成功
五、分别在keepalived01和keepalived02上启动Keepalived服务
[root@keepalived01 keepalived]# service keepalived start
[root@keepalived02 keepalived]# service keepalived start
通过ipvsadm -L命令查看VIP是否能成功映射到后端mycat服务。如果失败了,可通过/var/log/messages日志定位keepalived启动失败的原因。
[root@keepalived01 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.244.10:8066 rr persistent 50
-> 192.168.244.148:8066 Route 1 0 0
-> 192.168.244.149:8066 Route 1 0 0
[root@keepalived02 keepalived]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.244.10:8066 rr persistent 50
-> 192.168.244.148:8066 Route 1 0 0
-> 192.168.244.149:8066 Route 1 0 0
从输出的结果来看,VIP已成功映射到后端mycat服务,下面,具体测试一下
六、测试MyCAT高可用负载均衡集群的可用性。
测试MyCAT集群的负载均衡
通过mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'命令来判断当前访问的是哪个mycat节点。
但是很奇怪的时,连续执行三次,每次都是访问mycat02节点。
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
通过ipvsadm -L命令查看这三个连接确实都被转发到mycat02上了。
[root@keepalived01 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.244.10:8066 rr persistent 50
-> 192.168.244.148:8066 Route 1 0 0
-> 192.168.244.149:8066 Route 1 0 3
原来,这个与配置文件中的persistence_timeout有关,指的是在一定的时间内来自同一IP的连接将会被转发到同一realserver中。而不是严格意义上的轮询。默认为50s,具体的失效时间还是比较复杂,可参考:LVS持久性工作原理和配置 http://www.linuxidc.com/Linux/2016-03/129232.htm
在这里,为了观察到明显的轮询效果。将该值设为0。重启keepalived服务。
重新测试,结果如下
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat01 |
+------------+
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat01 |
+------------+
实现了严格意义上的轮询,ipvsadm -L的输出结果如下:
[root@keepalived01 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.244.10:8066 rr
-> 192.168.244.148:8066 Route 1 0 2
-> 192.168.244.149:8066 Route 1 0 2
每个节点对应2个连接,与上述通过mysql客户端得到的结果相符。
测试LVS的高可用
手动断开LVS-DR-Master节点的Keepalived服务
[root@keepalived01 ~]# service keepalived stop
Redirecting to /bin/systemctl stop keepalived.service
[root@keepalived01 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
可以发现,mysql客户端依旧可以通过mycat连接到mysql服务端
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB -e 'select @@hostname'
Warning: Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| mycat02 |
+------------+
重启LVS-DR-Master节点的Keepalived服务后,不难检测出keepalived01又重新作为了Master节点(因为BACKUP节点的persistence_timeout没有修改,所以可根据轮询的特点来判断哪个节点是master节点)。
测试Keepalived对于MyCAT服务的监控检测
手动关闭mycat01节点的mycat服务
[root@mycat01 ~]# cd /usr/local/mycat/
[root@mycat01 mycat]# bin/mycat stop
Stopping Mycat-server...
Stopped Mycat-server.
通过LVS-DR-Master节点节点上的ipvsadm -L可以看出VIP的映射关系中已剔除了mycat01节点。
[root@keepalived01 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.244.10:8066 rr
-> 192.168.244.149:8066 Route 1 0 0
至此,基于LVS+Keepalived的MyCAT集群搭建完毕。
在整个搭建过程中,有以下几点需要注意:
1. VIP的端口,必须和后端服务的端口是对应的,我在测试的过程中,将VIP的端口改为7066,结果无法连接上mycat。
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P7066 -utest -ptest -DTESTDB
Warning: Using a password on the command line interface can be insecure.
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.244.10' (111)
[root@mysql-server1 ~]# mysql -h192.168.244.10 -P8066 -utest -ptest -DTESTDB
Warning: Using a password on the command line interface can be insecure.
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.244.10' (111
2. LVS和后端的realserver还是要物理上分开,刚开始是放到一个机器上测试,但无法得到预期的效果。
3. interface eno16777736这里是个坑,刚开始写的是eth0,结果,ping都ping不通,所以还是要与网卡的实际名称相对应。
4. Keepalived还是蛮强大的,即便不使用LVS,也可基于它做高可用集群。譬如,常见的MySQL的双主高可用集群。
5. 关于是否要启动Linux内核中的路由转发功能,经测试,无论是LVS还是后端MyCAT服务节点,均可不启动。
MySQL主从复制之Mycat简单配置和高可用
什么是Mycat
1. Mycat就是MySQL Server,而Mycat后面连接的MySQL Server,就好象是MySQL的存储引擎,如InnoDB,MyISAM等.因此,Mycat本身并不存储数据,数据是在后端的MySQL上存储的,因此数据可靠性以及事务等都是MySQL保证的。
2. Mycat是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储.所以有了数据库中间件,应用只需要集中与业务处理,大量的通用的数据聚合,事务,数据源切换都由中间件来处理,中间件的性能与处理能力将直接决定应用的读写性能,所以一款好的数据库中间件至关重要。
术语
分片规则(rule)
逻辑库(schema)
分片节点(dataNode)
节点主机(dataHost)
Mycat使用
首先要安装,mysql5.7和mycat,并且两台主机要先做好mysql的主从复制,且两台主机的mysql都要存在db1数据库,用来存放mycat的数据.
关于mysql的主从复制,这里就不贴出了
配置mycat
vim wrapper.conf
wrapper.java.command=/usr/bin/java #java命令所在目录
wrapper.java.additional.5=-XX:MaxDirectMemorySize=2G 根据实际内存设置
wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=2984
定义mycat中可以创建的表,以及哪些节点可以使用哪些表
连接数据库的用户密码,稍后还要在数据库授权
因为做的是高可用,所以33和44都具有写的功能
vim schema.xml
server33,server44:
vim /etc/my.cnf
lower_case_table_names = 1
mysql>CREATE USER mycat identified by 'Mycat+007';
mysql>grant all privileges on *.* to mycat@'%';
配置成功,启动~
mycat start ,查看日志 wrapper.log
检验
mycat的登陆:
mysql -umycat -pMycat+007 -P8066 -h127.0.0.1
查看server44,和server33的mycat数据是否同步~
建表:
create table employee (id int not null primary key,name varchar(100),sharding_id int not null);
插入数据:
insert into employee(id,name,sharding_id) values(1,'leader us',10000);
insert into employee(id,name,sharding_id) values(2, 'me',10010);
insert into employee(id,name,sharding_id) values(3, 'mycat',10000);
insert into employee(id,name,sharding_id) values(4, 'mydog',10010);
在两台mycat上,都能看到相同的数据,即为成功
并且在server33和server44上的db1数据库中,也能看见刚刚创建的数据
heartbeat+drbd+mycat实现高可用分布式存储
存储:drbd
vim /etc/drbd.d/lalalala.res
resource lalalala {
meta-disk internal;
device /dev/drbd8;
syncer {
verify-alg sha1;
}
on server33.lalala.com {
disk /dev/vdc;
address 172.25.88.33:7789;
}
on server44.lalala.com {
disk /dev/vdb;
address 172.25.88.44:7789;
}
}
高可用
vim ha.cf
initdead 60 资源初始化时间,如果设置过大,接管时间可能很长,不用担心,只需要耐心等待~
vim haresources
server33.lalala.com IPaddr::172.25.88.100/24/eth0 drbddisk::lalalala Filesystem::/dev/drbd8::/home/mycat/app/mycat/lib::ext4 mycatd
其它配置照旧~
需要指出的是,因为mycat不属于LSB,所以要自己编写脚本启动文件,我写的太粗糙了,不要学我.....
vim /etc/init.d/mycatd 注意启动脚本的位置
path=/home/mycat/app/mycat/bin/mycat #路径为执行mycat的环境,可以用which查看
function usage(){
echo "$0 {start|stop|restart}"
exit 1
}
[ $# -ne 1 ] && usage #如果没有输入参数,就显示本脚本用法
case $1 in
start)
$path/mycat start # &>/dev/null &
;;
stop)
$path/mycat stop &>/dev/null &
;;
restart)
$path/mycat start &>/dev/null &
$path/mycat stop &>/dev/null &
;;
*)
printf "Usage:$0 {start|stop|restart}\n"
esac
启动server33的heartbeat!
可以看到IP,存储,服务全都启动拉!
查看挂载点和IP
高可用的接管,take over