ITPUX技术网

交流 . 资讯 . 分享
Make progress together!
Linux操作系统下Oracle11g R2 RAC 安装配置教程
Oracle数据库培训-备份恢复-性能优化-集群容灾
Oracle数据库DBA高级工程师培训视频

LVS + Keepalived + MyCAT搭建高可用负载均衡集群

内容发布:luashin| 发布时间:2017-6-8 20:12:05
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 {
     acassen@firewall.loc     #设置报警邮件地址,可以设置多个,每行一个。
     failover@firewall.loc    #需开启本机的sendmail服务
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc  #设置邮件的发送地址
   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 {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   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 <<EOF

# for java environment
export JAVA_HOME=/usr/local/jdk1.8.0_131
export JRE_HOME=\${JAVA_HOME}/jre
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH
EOF

--使/etc/profile文件生效
# source /etc/profile
# java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

2、安装MySQL
MySQL官方下载地址如下:
http://dev.mysql.com/downloads/mysql/

有各种版本,包括RPM,二进制,源码包。
为了方便起见,这里选择是RPM包
1)、下载YUM包
wget http://dev.mysql.com/get/mysql57-community-release-el6-8.noarch.rpm
2)、安装YUM包
rpm -ivh mysql57-community-release-el6-8.noarch.rpm && rm -rf mysql57-community-release-el6-8.noarch.rpm
sed -i '27s/0/1/' /etc/yum.repos.d/mysql-community.repo
sed -i '34s/1/0/' /etc/yum.repos.d/mysql-community.repo
yum clean all && yum makecache
3)、安装MySQL
添加属主及属组:
[root@node1 ~]# grep mysql /etc/passwd || (groupadd mysql && useradd -M -s /sbin/nologin -r -g mysql mysql)
卸载内置MySQL:
[root@node1 ~]# yum -y remove mysql-server mysqls-devel mysql && rpm -e --nodeps mysql-libs  
安装MySQL-5.6.36
[root@node1 ~]# yum -y install mysql-community-server

启动MySQL
# /etc/init.d/mysqld start
Starting mysqld (via systemctl):                           [  OK  ]

为root账户创建密码
# mysqladmin -u root password "123456"
建议为123456,后面MyCAT配置文件schema.xml中会用到

3、安装MyCAT
创建MyCAT用户并设置密码
# groupadd mycat && useradd -M -s /sbin/nologin -r -g mycat mycat && echo mycat | passwd --stdin mycat

解压MyCAT文件
# tar zxvf Mycat-server-1.5-alpha-20151221110028-linux.tar.gz -C /usr/local/
cd /usr/local/
mv -v Mycat-server-1.5-alpha-20151221110028-linux mycat

设置mycat目录的属主和属组
# chown -R mycat.mycat /usr/local/mycat/

4、测试MyCAT
首先在MySQL上创建三个数据库:db1,db2,db3。
[root@localhost ~]# mysql -uroot -pmysql
mysql> create database db1;
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中可以创建的表,以及哪些节点可以使用哪些表
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3"
                            rule="mod-long" />

                 <table name="employee" primaryKey="ID" dataNode="dn1,dn2"
                            rule="sharding-by-intfile" />
                 <table name="customer" primaryKey="ID" dataNode="dn1,dn2"
                            rule="sharding-by-intfile">
                         <childTable name="orders" primaryKey="ID" joinKey="customer_id"
                                                 parentKey="id">
                                 <childTable name="order_items" joinKey="order_id"
                                                         parentKey="id" />
                         </childTable>
                         <childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
                                                 parentKey="id" />
                 </table>

         <dataNode name="dn1" dataHost="server33.lalala.com" database="db1" />
         <dataNode name="dn2" dataHost="server33.lalala.com" database="db1" />
         <dataNode name="dn3" dataHost="server33.lalala.com" database="db1" />

         <dataHost name="server33.lalala.com" maxCon="1000" minCon="10" balance="0"
                           writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                 <heartbeat>select user()</heartbeat>
                 <!-- can have multi write hosts -->

连接数据库的用户密码,稍后还要在数据库授权
因为做的是高可用,所以33和44都具有写的功能
vim schema.xml
                 <writeHost host="hostM1" url="server33.lalala.com:3306" user="mycat"
                                    password="Mycat+007">
                         <!-- can have multi read hosts -->
                 </writeHost>
                 <writeHosthost="hostS1" url="server44.lalala.com:3306" user="mycat"
                                    password="Mycat+007">
                 </writeHost>

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




上一篇:Mycat实现数据库读写分离
下一篇:CentOS 6下安装部署Galera Cluster for MySQL集群
回复

使用道具 举报

1框架
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表