admin
不忘初心,方得始终
级别: 管理员
只看楼主 | | | 0楼 发表于:2015-10-19 22:54

MariaDB Master-Master+LVS Load Balance+Keepalived High Available

MariaDB Master-Master双主+Lvs+Keepalived配置DB业务的负载均衡和高可用环境
一.架构介绍
  架构介绍:利用Keepalived构建高可用的MariaDB-HA,保证两台MariaDB数据的一致性,然后用Keepalived实现虚拟IP,通过Keepalived自带的服务监控功能来实现MariaDB故障时自动切换。Keepalived的设计目的是构建高可用的LVS负载均衡集群,可以调用ipvsadm工具来创建虚拟服务器,管理服务器池,而不仅仅用来做双机热备。使用keepalived构建LVS集群更加简单易用,主要优势体现在:1.对LVS负载均衡调度器实现热备切换,提高可用性。2.对服务器池中的节点进行健康检查,自动移除失效节点,恢复后再重新加入。在基于 LVS+Keepalived实现的LVS群集结构中,至少包括2台热备的负载调度器,两台以上的节点服务器。本例中以DR模式的LVS群集为基础,增加负载调度器,使用Keepalived来实现调度器的热备,从而构建建有负载均衡、高可用两种能力的LVS网站群集平台。Keepalived可以实现高可用或者热备,用来防止单点故障的问题,而Keepalived的核心是VRRP协议,VRRP协议主要实现了在路由器或者三层交换机处的冗余,Keepalived就是使用VRRP协议来实现高可用。通过LVS+Keepalived构建的LVS集群,LVS负载均衡用户请求到后端的MariaDB服务器,Keepalived的作用是检测MariaDB服务器的状态,如果有一台MariaDB服务器宕机,或者工作出现故障,Keepalived将检测到,并且将有故障的MariaDB服务器从系统中剔除,当MariaDB服务器工作正常后Keepalived自动将MariaDB服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的MariaDB服务器。
  硬件拓扑图:
  MariaDB M-M+LB+HA

  VIP:10.10.10.246
  MariaDB1:10.10.10.244
  MariaDB2:10.10.10.245
  MariaDB-test:10.10.10.247
  CentOS Version:CentOS 6.4_64
  Keepalived Version:v1.2.13
  MariaDB Version:10.0.21
  Ipvsadm Version:v1.26
  说明:正式生产环境需要LVS+Keepalived部署在2个VM上,后端业务服务器mariadb分别部署在2个VM上。这样,LVS+Keepalived可以实现负载均衡和高可用的功能。

二.安装软件:
2.1 安装CentOS 6.4_64系统。

2.2 打开iptables服务。
/etc/init.d/iptables start
/sbin/iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
/sbin/iptables -I INPUT -p vrrp -j ACCEPT
/sbin/iptables -I OUTPUT -p vrrp -j ACCEPT
/etc/init.d/iptables save
/etc/init.d/iptables restart

2.3 关闭selinux功能及设置内核参数:
vim /etc/sysconfig/selinux
设置SELINUX=disabled
Setenforce 0临时关闭selinux
使用getenforce 查看selinux的状态。

echo "1" >/proc/sys/net/ipv4/ip_forward
/sbin/sysctl -p

2.4 设置时区、时钟同步以及iptables打开UDP123端口。
防火墙打开UDP 123端口,进行时钟同步需要开启UDP123端口。
/sbin/iptables –I INPUT –p udp –dport 123 –j ACCEPT
/etc/init.d/iptables save
/etc/init.d/iptables restart

cp /usr/share/zoneinfo/Asia/Shang /etc/localtime 设置cst-8东八区区时
yum install ntp –y
ntpdate –d ntp.api.bz 或者ntpdate –d cn.pool.ntp.org
crontab  -e
输入* * * * * ntpdate ntp.api.bz或者* * * * * ntpdate cn.pool.ntp.org
/etc/init.d/crond restart
date –R 查看+800为东八区区时。

2.5修改网卡、网关、DNS和主机名。
分别修改/etc/sysconfig/network-script/ifcfg-eth0、/etc/sysconfig/network、/etc/resolv.conf和/etc/hosts文件。
[root@mariadb1 network-scripts]# more ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.10.10.244
NETMASK=255.255.255.0
[root@mariadb1 network-scripts]# more /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=mariadb1
GATEWAY=10.10.10.1
[root@mariadb1 network-scripts]# more /etc/resolv.conf
; generated by /sbin/dhclient-script
search openstacklocal
nameserver 114.114.114.114
[root@mariadb1 network-scripts]# more /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.10.244 mariadb1

2.6 卸载mysql的软件包。
rpm –e mysql-libs –nodeps

2.7 设置MariaDB的源。
cd /etc/yum.repos.d/
新增一个文件,内容如下:
vim /etc/yum.repos.d/MariaDB.repo
[mariadb]
name=MariaDB
baseurl = http://yum.mariadb.org/10.0/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

2.8安装MariaDB的软件包。
yum -y install MariaDB-client MariaDB-server MariaDB-devel
service mysql on
chkconfig mysql on

2.9 设置MariaDB的root密码,进行安全加固。
/usr/bin/mysql_secure_installation

2.10 MariaDB设置双主,设置双主同mysql主从过程相同。双主是互为主从。需要先对用户进行授权,然后刷新权限。
在MariaDB1上执行语句:
grant replication slave,replication client on *.* to 'abc222'@'10.10.10.245' identified by 'eayun123.com';
flush privileges;
在MariaDB2上执行语句:
grant replication slave,replication client on *.* to 'abc222'@'10.10.10.244' identified by 'eayun123.com';
flush privileges;

2.11 MariaDB设置双主的配置文件。
在MariaDB1上配置自增ID为奇数,自增值为2.
[root@mariadb1 yum.repos.d]# more /etc/my.cnf|grep -v '#'|grep -v '^$'
[client-server]
!includedir /etc/my.cnf.d
[mysqld]
log_slave_updates
log-bin = mysql-bin
server-id = 1
binlog-ignore-db = mysql
auto-increment-increment = 2
auto-increment-offset = 1

在MariaDB2上配置自增ID为偶数,自增值为2.
[root@mariadb2 ~]# more /etc/my.cnf|grep -v '#'|grep -v '^$'
[client-server]
!includedir /etc/my.cnf.d
[mysqld]
log_slave_updates
log-bin = mysql-bin
server-id = 2
binlog-ignore-db = mysql
auto-increment-increment = 2
auto-increment-offset = 2
2.12 设置MariaDB主从,然后设置双主。
首先以mariadb1为主,mariadb2为从。
在Mariadb1上通过mysql –uroot –p登录到MariaDB本地。
输入:
show master status;记录下来mysql-bin的文件名和位置。
在Mariadb2上通过mysql –uroot –p登录到MariaDB本地。
执行slave stop;
change master to master_host='10.10.10.244',master_user=' abc222',master_password=' eayun123.com ',master_log_file='mysql-bin.0000XX',master_log_pos=XXX;
执行slave start;
查看从库状态:show slave status\G;

再次以mariadb2为主,mariadb1为从。
在Mariadb2上通过mysql –uroot –p登录到MariaDB本地。
输入:
show master status;记录下来mysql-bin的文件名和位置。
在Mariadb1上通过mysql –uroot –p登录到MariaDB本地。
执行slave stop;
change master to master_host='10.10.10.245',master_user=' abc222',master_password=' eayun123.com ',master_log_file='mysql-bin.0000XX',master_log_pos=XXX;
执行slave start;
查看从库状态:show slave status\G;

2.13 安装Keepalived 软件包,以及编写MariaDB的状态检测脚本。
yum install keepalived –y
mariadb1上设置MariaDB的状态自动检测脚本及配置Keepalived:
[root@mariadb1 yum.repos.d]# more /root/check_mysql.sh |grep -v '#'|grep -v '^$'
MYSQL=/usr/bin/mysql
MYSQL_HOST=localhost
MYSQL_USER=root
MYSQL_PASSWORD=eayun\)\(\*2015
CHECK_TIME=3
MYSQL_OK=1
function check_mysql_helth (){  
$MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "show status;" >/dev/null 2>&1
        if [ $? = 0 ] ;then  
                MYSQL_OK=1
        else  
                MYSQL_OK=0
        fi  
        return $MYSQL_OK  
}  
while [ $CHECK_TIME -ne 0 ]  
do  
     let "CHECK_TIME -= 1"  
     check_mysql_helth  
     if [ $MYSQL_OK = 1 ] ; then  
          CHECK_TIME=0
          exit 0  
     fi  

     if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]  
     then  
          /etc/init.d/keepalived stop  
     exit 1  
     fi  
     sleep 1  
done

[root@mariadb1 yum.repos.d]# more /etc/keepalived/keepalived.conf|grep -v '#'|grep -v '^$'
! Configuration File for keepalived
global_defs {
    router_id LVS_SLAVE
}
vrrp_script check_mysql {
    script "/root/check_mysql.sh"
    interval 3
}
vrrp_sync_group VG1 {
     group {
        VI_1
     }
}
vrrp_instance VI_1 {
     state MASTER
     interface eth0
     virtual_router_id 51
     priority 100  优先级一定要比备用节点的高
     advert_int 1
     nopreempt  设置不抢占
     authentication {
         auth_type PASS
         auth_pass kinda22
     }
     track_script {
         check_mysql
     }
     virtual_ipaddress {
         10.10.10.246
     }
}
virtual_server 10.10.10.246 3306 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP
    real_server 10.10.10.244 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 10.10.10.245 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}
Mariadb2上设置MariaDB的状态自动检测脚本及配置Keepalived:
[root@mariadb2 ~]# more /root/check_mysql.sh |grep -v '#'|grep -v '^$'
MYSQL=/usr/bin/mysql
MYSQL_HOST=localhost
MYSQL_USER=root
MYSQL_PASSWORD=eayun\)\(\*2015
CHECK_TIME=3
MYSQL_OK=1
check_mysql_helth (){  
        $MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "show status;" >/dev/null 2>&1  
        if [ $? = 0 ] ;then  
                MYSQL_OK=1
        else  
                MYSQL_OK=0
        fi  
        return $MYSQL_OK  
}  
while [ $CHECK_TIME -ne 0 ]  
do  
     let "CHECK_TIME -= 1"  
     check_mysql_helth  
     if [ $MYSQL_OK = 1 ] ; then  
          CHECK_TIME=0
          exit 0  
     fi  

     if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]  
     then  
          /etc/init.d/keepalived stop  
     exit 1  
     fi  
     sleep 1  
done  

[root@mariadb2 ~]# more /etc/keepalived/keepalived.conf|grep -v '#'|grep -v '^$'
! Configuration File for keepalived
global_defs {
    router_id LVS_SLAVE
}
vrrp_script check_mysql {
    script "/root/check_mysql.sh"
    interval 3
}
vrrp_sync_group VG1 {
     group {
        VI_1
     }
}
vrrp_instance VI_1 {
     state BACKUP
     interface eth0
     virtual_router_id 51
     priority 99  优先级一定要比主节点低
     advert_int 1
     nopreempt  设置不抢占
     authentication {
         auth_type PASS
         auth_pass kinda22
     }
     track_script {
         check_mysql
     }
     virtual_ipaddress {
         10.10.10.246
     }
}
virtual_server 10.10.10.246 3306 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP
    real_server 10.10.10.244 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
   real_server 10.10.10.245 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}
/etc/init.d/keepalived

2.14 2.14 VM所在物理机设置内核参数
sysctl -w net.bridge.bridge-nf-call-iptables=1
sysctl –p

2.15 部署LVS负载均衡。
Mariadb1上的配置与mariadb2上的配置一样。
[root@mariadb1 yum.repos.d]# vim /root/ipvsadm_conf.sh
#!/bin/bash
/sbin/ipvsadm -C
/sbin/ipvsadm -A -t 10.10.10.246:3306 -s wrr
/sbin/ipvsadm -a -t 10.10.10.246:3306 -r 10.10.10.244:3306 -g -w 1
/sbin/ipvsadm -a -t 10.10.10.246:3306 -r 10.10.10.245:3306 -g -w 1
service ipvsadm save

chmod 755 /root/ipvsadm_conf.sh
./root/ipvsadm_conf.sh start

[root@mariadb1 yum.repos.d]# vim /etc/init.d/lvsdr.sh
#!/bin/bash
VIP=10.10.10.246                  
. /etc/rc.d/init.d/functions                    
case "$1" in
start)
    /sbin/ifconfig lo down  
    /sbin/ifconfig lo up        
    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    
    /sbin/sysctl -p >/dev/null 2>&1
    /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 up
    /sbin/route add -host $VIP dev lo:0  
    echo "LVS-DR real server starts successfully."                    
    ;;    
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 "LVS-DR real server stopped."
    ;;
status)
    isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"`
    isRoOn=`/bin/netstat -rn | grep "$VIP"`
    if [ "$isLoOn" == "" -a "$isRoOn" == "" ]; then
       echo "LVS-DR real server has to run yet."
    else
       echo "LVS-DR real server is running."
    fi
    exit 3
    ;;
*)    
    echo "Usage: $0 {start|stop|status}"
    exit 1    
esac                    
exit 0

chmod 755 /etc/init.d/lvsdr.sh
/etc/init.d/lvsdr.sh start

三.业务验证:
1.通过测试机10.10.10.247使用命令登录VIP的地址和端口,并且通过ipvsadm –Ln命令查看客户端请求经过LVS负载均衡分发的情况:
mysql –h 10.10.10.246 –uroot –peayun\)\(\*2015
2.通过mariadb连接后创建数据库,写入数据,并且查看。
mysql –h 10.10.10.246 –uroot –peayun\)\(\*2015
create database mysqltest;
CREATE TABLE `ttt` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(16) NOT NULL,
  PRIMARY KEY (`id`)
);
insert into ttt values('','aaa1');
insert into ttt values('','aaa2');
insert into ttt values('','aaa3');
exit
mysql –h 10.10.10.246 –uroot –peayun\)\(\*2015
insert into ttt values('','bbb1');
insert into ttt values('','bbb2');
insert into ttt values('','bbb3');
exit

select * from ttt;查看可以看到,LVS分发到mariadb的配置文件/etc/my.cnf里面参数auto-increment-offset = 1时候,ttt表中的ID是奇数。/etc/my.cnf里面参数auto-increment-offset = 2时候,ttt表中的ID是偶数。

3.停止其中一个业务系统上面的keepalived服务,Keepalived的VIP会漂移到另外一个系统。
service keepalived restart 然后通过ip a查看VIP所在的VM,并且通过more /var/log/messages查看到VRRP的协议状态,以及Keepalived的Master/Backup的状态切换。
Keepalived的master与slave通过VRRP2协议进行通信,以决定各自的状态及VIP等相关信息,master会发送广播包,广播地址为:224.0.0.18.抓包可以分析,命令为:
tcpdump -X -n -vvv 'dst 224.0.0.18'。
4.停掉其中一个业务系统的mariadb服务,进行测试。从另外一个业务系统通过ipvsadm –Ln命令发现业务系统经过Keepalived进行健康检查,从集群中被剔除,并且Keepalived服务已经停止。
5.需要特别注意的是:mariadb服务属于数据库服务,为了安全性,不需要进行公网IP地址的配置,连接DB都通过内网进行。