之前写过了MySQL的简单MHA环境搭建,但是mha只是保证数据库一致性,对于实现应用访问的固定入口、读写分离、负载均衡需要keepalived、中间件、lvs来解决了。

本次搭建使用四台虚拟机,如下
manger:192.168.1.10
db1 (主):192.168.1.11
db2 (备):192.168.1.12
db3 (从):192.168.1.13

一、环境搭建
1、mha
      前面写过,这里就不说了

2、keepalived
      keepalived通常是用来防止单点故障造成集群失效,本例使用keepalived主要是两个作用,一个是防止单点故障,一个是用两个vip做读写分离,关于配置继续看步骤3。

3、读写分离
      读写分离有两种方式,一种是用keepalived,对外使用两个ip,分别对应写vip读vip;一种是用中间件,对外就是一个ip。
      本例使用keepalived,三台机器的配置文件内容除过红色以外都一样。
      注意:在同一网段内virtual_router_id 值不能相同;priority由优先级从大到小;

global_defs {
    router_id LVS_DEVEL
 }

 vrrp_instance VI_1 {
     state BACKUP
     interface eth0
     virtual_router_id 60
     priority 100
     advert_int 1
     nopreempt
     authentication {
         auth_type PASS
         auth_pass 1111
     }
     virtual_ipaddress {
         192.168.1.21
         192.168.1.22
     }
 }

 virtual_server 192.168.1.21 3306 {
     delay_loop 2
     lb_algo rr
     lb_kind DR
     nat_mask 255.255.255.0
     protocol TCP

     real_server 192.168.1.11 3306 {
         weight 1
         notify_down /usr/local/mysql/mysqldown.sh 
         TCP_CHECK {
             connect_port 3306
             connect_timeout 3
             nb_get_retry 3
             delay_before_retry 3
         }
     }
     real_server 192.168.1.12 3306 {        weight 1
         notify_down /usr/local/mysql/mysqldown.sh 
         TCP_CHECK {
             connect_port 3306
             connect_timeout 3
             nb_get_retry 3
             delay_before_retry 3
         }
     }
 }

 virtual_server 192.168.1.22 3306 {
     delay_loop 2
     #wrr是lvs的均衡算法
     lb_algo wrr
     lb_kind DR
     nat_mask 255.255.255.0
     protocol TCP

     real_server 192.168.1.12 3306 {
         weight 1
         notify_down /usr/local/mysql/mysqldown.sh 
         TCP_CHECK {
             connect_port 3306
             connect_timeout 3
             nb_get_retry 3
             delay_before_retry 3
            }
      }
     real_server 192.168.1.13 3306 {
         weight 1
         notify_down /usr/local/mysql/mysqldown.sh 
         TCP_CHECK {
             connect_port 3306
             connect_timeout 3
             nb_get_retry 3
             delay_before_retry 3
            }
      }
 }


注:当192.168.1.11正常时,192.168.1.12用来读;当192.168.1.11宕机时,192.168.1.12用来写,所以在两个vip中192.168.1.12都出现了。

4、读的负载均衡
(1)  安装lvs
[root@localhost]# yum install ipvsadm
(2)  新建realserver.sh并配置

[root@localhost]# vim /etc/rc.d/init.d/realserver.sh
 #!/bin/bash
 # description: Config realserver lo and apply noarp
 SNS_VIP=192.168.1.22
 source /etc/rc.d/init.d/functions
 case "$1" in
 start)
        ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
        /sbin/route add -host $SNS_VIP dev lo:0
        /sbin/route add -host $SNS_VIP2 dev lo:1
        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)
        ifconfig lo:0 down
        route del $SNS_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


二、启动
1、 启动Master上的MySQL
service mysql start
2、 启动Slave上的MySQL
service mysql start
3、 启动Master上的realserver脚本
/etc/rc.d/init.d/realserver.sh start
4、 启动Slave上的realserver脚本
/etc/rc.d/init.d/realserver.sh start
5、 启动Master上的keepalived
service keepalived start
6、 启动Slave上的keepalived
service keepalived start

三、测试
1、读写分离
      关于读写分离已经用不同的vip区分,使用不同的vip进行读、写。
2、负载均衡
(1)、查看lvs能否进行负载均衡转发
db1、db2、db3做相同的命令

[root@localhost ~]# ipvsadm -ln
 IP Virtual Server version 1.2.1 (size=4096)
 Prot LocalAddress:Port Scheduler Flags
   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
 TCP  192.168.1.21:3306 rr
   -> 192.168.1.11:3306              Local   1      4          0         
 TCP  192.168.1.22:3306 wrr
   -> 192.168.1.12:3306              Route   1      0          0         
   -> 192.168.1.13:3306              Route   1      0          0



IP使用该机器所用的vip
[root@localhost ~]# ipvsadm -lcn | grep 192.168.1.21
TCP 14:22  ESTABLISHED 192.168.1.56:64934   192.168.1.21:3306    192.168.1.11:3306
TCP 14:23  ESTABLISHED 192.168.1.56:64935   192.168.1.21:3306    192.168.1.11:3306
TCP 14:05  ESTABLISHED 192.168.1.56:64928   192.168.1.21:3306    192.168.1.11:3306
TCP 00:24  ESTABLISHED 192.168.1.56:64457   192.168.1.21:3306    192.168.1.11:3306

3、keepalived
(1)、测试db1宕机后,vip能否正常移动到db2
(2)、测试db1宕机后,db1加入到集群的两种方式
   a、db1以备库的身份加入集群:在db1上执行change master to ... db2;重新启动db1的keepalived
   b、db1以主库的身份加入集群:db1清空之前的binlog,db2、db3上reset slave all并执行change master to ...db1; 重新启动db1的keepalived;重新启动mha管理节点
    注意:b的方式比较繁琐,而且b如果重新为主,mha在重新启动中可能会对db2的binlog文件进行报错,需要较多时间才能正常启动,建议用a的方式;
                使用show VARIABLES like '%server_id%'来确认keepalived的vip在哪台机器上;
                无论a、b方式,有新节点加入集群时,一定要注意数据一致性

-------------------------------------