集群-高可用-HA

集群

集群的概述
1.集群是一组协同工作的服务实体
#每个节点提供相同服务,当一个服务down掉,自动切换备用服务

2.集群实体的可扩展性
#可以增加备用节点,也可以减少备用节点

3.集群实体的高可用性
#在集群中同一服务可以由多个服务节点提供,当部分服务节点失效后,其它服务节点可以接管服务。

4.集群实体地址
#指客户端访问集群实体获取服务资源的唯一入口地址,比如访问nginx只要通过浮动ip就可以访问了。

5.客户请求的负载均衡
#指集群中的分发设备(服务)将用户的请求任务比较均衡(不是平均)分布到集群实体中的服务节点

6.服务节点的错误恢复
#指集群中某个或某些服务节点(设备)不能正常工作(或提供服务),其它类似服务节点(设备)可以资源透明和持续的完成原有任务。!!!

HA集群的类型:

keepalived工作原理:
keepalive原理很简单,TCP会在空闲了一定时间后发送数据给对方:
1.如果主机可达,对方就会响应ACK应答,就认为是存活的。
2.如果可达,但应用程序退出,对方就发FIN应答,发送TCP撤消连接。
3.如果可达,但应用程序崩溃,对方就发RST消息。
4.如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。这个时间就是默认
的二个小时。

1. 主从
从服务器不对外提供服务,监控主服务器,如果主服务器出现故障,不能对外提供服务,那么从服务器会使用故障迁移,将资源从主服务器拿过来,由“自己”对外提供服务。

从服务器使用心跳检测链路监控主服务器。

2. 对称
2个节点都对外提供服务,互相监视。

脑裂(裂脑)
在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样,争抢“共享资源”、争起“应用服务”,就会发生严重后果——或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏(常见如数据库轮询着的联机日志出错)。

产生脑裂的原因:
(1)心跳线故障
(2)网卡或驱动故障
(3)心跳连接的设备故障
(4)ip地址冲突,基本不会发生
(5)防火墙拦截了心跳数据包的传输

连接心跳的方式:
(1)串口线直连,有距离限制
(2)网线直连
直连的方式只适用于双节点
(3)使用交换机,通过网线连接
使用最多
要保证链路的纯净!!!

解决脑裂:
(1)心跳线冗余
(2)做好监控
一旦出现故障切换,报警要触发动作。
(3)仲裁
让节点完成ping 网关或存储 的动作,
能完成,证明节点是好的
不能完成,节点故障,自动放弃争抢

  1. 多机
    3个节点都对外提供服务,互相监视。

HA集群的存活条件是节点的票数要过半数!!!
默认一个节点的票数是1票。

在双节点模式的集群,这个功能需要关掉。

三节点节点,在down掉2个节点的时候,集群就宣布死亡。
为了保证在这种情况下,集群还是存活的,仲裁磁盘带有票数。
仲裁磁盘有2票就可以了。


HA集群的概念:

服务
浮动IP
成员服务器或节点
失效域
心跳
共享存储

单一故障点
仲裁
失效迁移
监视器

高可用:
在Centos7和Centos6系统中都可以使用keepalived作为高可用
高可用是一样的;

负载均衡:
Centos6 建议使用piranha,
Centos7 使用keepalived


HA集群

使用keepalive在centos7环境部署nginx的HA集群:
准备
nginx1 172.16.0.31
nginx2 172.16.0.32

准备工作:
关闭selinux iptables
主机名
/etc/hosts
联网
同步时间

开始配置:

下载keepalived

[root@nginx1 ~]# yum install -y keepalived
[root@nginx2 ~]# yum install -y keepalived

修改keepalived配置文件

[root@nginx1 ~]# cd /etc/keepalived/
[root@nginx1 /etc/keepalived]# ls
keepalived.conf
[root@nginx1 /etc/keepalived]# vim keepalived.conf 
! Configuration File for keepalived
global_defs {
   router_id Nginx_HA_xxs		!# 实现关联
	!#HA的唯一标识
}
vrrp_script check_run {
    script "/root/check_nginx.sh"
    interval    2
	!#监视器-脚本的路径
	!#检查的时间间隔,秒
}
vrrp_sync_group VG1 {			!# 实现关联
    group {
        VI_1
    }   
	!#定义了一个实例组
} 
vrrp_instance VI_1 {
	!#第一个实例
    state BACKUP
	!#工作模式
!# MASTER 主
!# BACKUP 备
    interface ens32
    virtual_router_id 199		!# 实现关联  (不同的服务是通过这个区分的)
!# id virtual_router_id 取值在0-255之间,用来区分多个instance的VRRP组播 数不能过大
	!#唯一标识的ID号
    priority 100
	!#优先级
    advert_int 1
	!#检查间隔
    nopreempt
	!#资源与服务不抢回
    authentication {
        auth_type PASS
        auth_pass nginxHA
    }
	!#验证方式,密码
    track_script {			<--- 这套东西别忘了
        check_run
    }
	!#使用上面定义的监视器脚本
    virtual_ipaddress {
        172.16.0.30 dev ens32 label ens32:0
	!#浮动IP,绑在哪个网卡上,( 浮动ip是没设置过的 )
    }
}

监视器-脚本:

[root@nginx1 ~]# yum install -y elinks
[root@nginx2 ~]# yum install -y elinks

[root@nginx1 ~]# vim check_nginx.sh
#!/bin/bash
# nginx的健康检查脚本

ELINKS="/usr/bin/links"
HOST="172.16.0.31"
GW="172.16.0.254"
CHECK_TIME=3

function check_nginx_health () {
# 三层检查
    ping -W 1 -c1 $GW &> /dev/null
    if [ $? -eq 0 ]
        then
# 七层检查
        $ELINKS -dump 1 $HOST &> /dev/null	# 访问自己的页面ip,检查nginx服务是否开启
        if [ $? -eq 0 ]
            then
            NGINX_OK=1
        else
            NGINX_OK=0
        fi
    else
        NGINX_OK=0
    fi
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME-=1"
    check_nginx_health
    if [ $NGINX_OK -eq 1 ]
        then
        CHECK_TIME=0
        exit
    fi
    if [ $NGINX_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
        then
        systemctl stop keepalived
        exit 1
    fi
    sleep 1
done

检查脚本是否可用

检查脚本是否可用
[root@nginx1 ~]# chmod +x check_nginx.sh 
[root@nginx1 ~]# ./check_nginx.sh 
[root@nginx1 ~]# echo $?	# 返回值为0,证明状态可用
0

将脚本和keepalived配置文件拷贝给关联节点

[root@nginx1 ~]# scp check_nginx.sh 172.16.0.32:/root/

相同的脚本,在脚本中ip设置成自己的ip
[root@nginx2 ~]# vim check_nginx.sh
HOST="172.16.0.32"

[root@nginx2 ~]# ./check_nginx.sh 
[root@nginx2 ~]# echo $?
0

配置文件传给对方即可,不需要修改配置文件
[root@nginx1 /etc/keepalived]# scp keepalived.conf 172.16.0.32:/etc/keepalived/

启动keepalived服务,并设置成开机自启动
[root@nginx1 ~]# systemctl start keepalived
[root@nginx1 ~]# echo "systemctl start keepalived" >> /etc/rc.local 
[root@nginx1 ~]# chmod +x /etc/rc.d/rc.local 

[root@nginx2 ~]# systemctl start keepalived
[root@nginx2 ~]# echo "systemctl start keepalived" >> /etc/rc.local 
[root@nginx2 ~]# chmod +x /etc/rc.d/rc.local 

能查看到虚拟网卡存在浮动ip就是设置成功了
虚拟网卡的ip,只存在于一台设备上,当一个设备关机或者keepalived服务停止后,
浮动ip会自动配置到另一个节点上
[root@nginx1 ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.0.30  netmask 255.255.255.255  broadcast 0.0.0.0

开始测试:

测试HA的牢固性

模拟测试:节点服务崩溃

1. 浮动IP在nginx1上
[root@nginx1 ~]# /usr/local/nginx/sbin/nginx -s stop

[root@nginx1 ~]# ifconfig 

[root@nginx2 ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.0.30  netmask 255.255.255.255  broadcast 0.0.0.0

结果:浮动IP切换到nginx2。

模拟测试:节点服务断网

由于上边服务停止了,这里需要重新启动
[root@nginx1 ~]# /usr/local/nginx/sbin/nginx 
[root@nginx1 ~]# systemctl start keepalived

模拟断网,讲nginx2重新启动,这样网络就切断了
[root@nginx2 ~]# reboot

节点1获得浮动ip
[root@nginx1 ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.0.30  netmask 255.255.255.255  broadcast 0.0.0.0

nginx端口正常
[root@nginx2 ~]# netstat -antp |  grep nginx
tcp        0      0 0.0.0.0:80     0.0.0.0:*    LISTEN      931/nginx

keepalived启动正常
[root@nginx2 ~]# ps aux | grep keepalived
root        935  0.0  0.1 118676  1384 ?        Ss   15:41   0:00 /usr/sbin/keepalived -D
root        936  0.0  0.2 118676  2612 ?        S    15:41   0:00 /usr/sbin/keepalived -D
root        937  0.0  0.2 120800  2504 ?        S    15:41   0:00 /usr/sbin/keepalived -D

重启节点1
[root@nginx1 ~]# reboot

节点2获得ip
[root@nginx2 ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.0.30  netmask 255.255.255.255  broadcast 0.0.0.0

[root@nginx1 ~]# netstat -antp | grep nginx
tcp        0      0 0.0.0.0:80      0.0.0.0:*    LISTEN      931/nginx

[root@nginx1 ~]# ps aux | grep keepalived
root        935  0.0  0.1 118676  1388 ?        Ss   15:42   0:00 /usr/sbin/keepalived -D
root        936  0.0  0.2 118676  2616 ?        S    15:42   0:00 /usr/sbin/keepalived -D
root        937  0.0  0.2 120800  2508 ?        S    15:42   0:00 /usr/sbin/keepalived -D

注意事项:!!!
keepalived的守护进程一定要在服务启动之后,再启动。
当设置rc.local自启动时,需要检查服务和keepalived的启动顺序,配置脚本时,要设置一定的延时时间。


mysql的HA集群:

准备:

  1. 2个mysql
    AA模式

    克隆mysql,注意 server_UUID

  2. 探测mysql的可用性?
    授权一个只读的用户
    mysql -u 用户名 -p密码 -e “quit” &> /dev/null

先配置双A模式的mysql。

在centos7环境,使用keepalive搭建mysql的HA集群:

mysqlA1 172.16.0.71
mysqlA2 172.16.0.72
浮动IP 172.16.0.60

  1. 配置mysql双A
[root@mysql-bin ~]# vim /etc/my.cnf		# 添加字符集必须结束mysql进程在启动才能生效
[mysqld]
	添加字符集设置
character-set-server = utf8
collation-server = utf8_general_ci
server-id       = 71				# 在每个节点分别设置各自的server-id
gtid_mode       = on					# 双A模式也需要分别设置这两项
	开启使用gtid
enforce_gtid_consistency    = 1			# 双A模式也需要分别设置这两项

Mysql设置

A端
mysql> grant replication slave,reload,super on *.* to slave@'172.16.0.72' identified by '12345';
mysql> flush privileges;

B端
mysql> change master to
    -> master_host='172.16.0.71',
    -> master_port=3306,
    -> master_user='slave',
    -> master_password='12345',
    -> master_auto_position=1;

mysql> start slave;

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.0.71
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000011
          Read_Master_Log_Pos: 655
               Relay_Log_File: slave_relay_bin.000004
                Relay_Log_Pos: 862
        Relay_Master_Log_File: binlog.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

反向再配置一遍就是双A了。

  1. 配置HA集群
! Configuration File for keepalived
global_defs {
   router_id mysqlHA_xxs
}
vrrp_script check_run {
    script "/root/check_mysql.sh"
    interval    2
}
vrrp_sync_group VG1 {
    group {
        VI_1
    }
}
vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 106
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass mysqlHA
    }
    track_script {
        check_run
    }
    virtual_ipaddress {
        172.16.0.60 dev ens32 label ens32:0
    }
}

添加一个测试用户

(探测脚本要用)

mysql> grant select on *.* to test@'localhost' identified by '12345';
mysql> flush privileges;

mysql健康检查的脚本

#!/bin/bash
# mysql的健康检查脚本

GW="172.16.0.254"
CHECK_TIME=3

function check_mysql_health () {
# 三层检查
    ping -W 1 -c1 $GW &> /dev/null
    if [ $? -eq 0 ]
        then
# 七层检查
        /usr/local/mysql/bin/mysql -u test -p12345 -e "quit" &> /dev/null
        if [ $? -eq 0 ]
            then
            MySQL_OK=1
        else
            MySQL_OK=0
        fi
    else
        MySQL_OK=0
    fi
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME-=1"
    check_mysql_health
    if [ $MySQL_OK -eq 1 ]
        then
        CHECK_TIME=0
        exit
    fi
    if [ $MySQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
        then
        systemctl stop keepalived
        exit 1
    fi
    sleep 1
done
[root@mysql01 ~]# vim check_mysql.sh 
#!/bin/bash
# 检查mysql的可用性

HOST="172.16.14.32"
GW="172.16.0.254"
CHECK_TIME=3

function check_mysql_health () {
#三层检查
    ping -W 1 -c1 $GW &> /dev/null
    if [ $? -eq 0 ]
        then
    /usr/local/mysql/bin/mysql -u test -p12345 -e "quit" &> /dev/null
        if [ $? -eq 0 ]
            then
            Mysql_OK=1
        else
            Mysql_OK=0
        fi
    else
        Mysql_OK=0
    fi
}

while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME-=1"
    check_nginx_health
    if [ $Mysql_OK -eq 1 ]
        then
        CHECK_TIME=0
        exit
    fi
    if [ $Mysql_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
        then
        systemctl stop keepalived
        exit 1
    fi
    sleep 1
done

发布了57 篇原创文章 · 获赞 3 · 访问量 998

猜你喜欢

转载自blog.csdn.net/weixin_42502744/article/details/103663631