preface

Mysql+drbd+heart能够实现Mysql的高可用了,master出现故障的时候能够快速切换。在现在的业务情况下,读操作多,写操作少的情况下,一台DB server明显扛不住,这时候我们需要读写分离,一台master承担写操作,多台承担读操作。如果仍然采用heartbeat+DRBD来实现Slave的高可用性,那么成本太大了。而且,有时候DB slave宕机是在夜间,这个时候也就要求不及时处理故障也不会影响业务(也就是一有故障就会自动退出服务集群),这个时候我们可以采用LVS+Keepalived来实现我们要的功能。

切换mysql slave的master服务器IP

我们之前做mysql主从同步的时候,slave使用的是172.16.22.81作为master的IP,这个时候我们需要修改成heartbeat的VIP。

在master上查看master当前log-bin的状态:

mysql> show master status;            # 在172.16.22.136上操作,因为VIP在这里
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000017 | 387 | | |
+-------------------+----------+--------------+------------------+

在所有的slave上操作下面的语句,host为mysql的VIP

mysql> stop slave;
mysql> change master to master_host='172.16.22.250',master_user='rep',master_password='123456',master_log_file='mysqld-bin.000017',master_log_pos=387;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.22.250
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysqld-bin.000017
Read_Master_Log_Pos: 387
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysqld-bin.000017
Slave_IO_Running: Yes #确认同步状态
Slave_SQL_Running: Yes #确认同步状态
安装LVS+keepalived

我们采用yum安装keepalived和LVS。

在172.16.22.162和172.16.22.163上安装ipvsadm keepalived Mysql。要安装mysql,因为后面的健康探测脚本需要使用mysql命令。还有说下,安装完以后并没有对keepalived做开机自启动,自己根据实际情况做开机自启动。

[root@lvsbackup192 ~]# yum -y install ipvsadm keepalived  mysql

安装好以后, 我们配置172.16.22.162的keepalived

[root@lvsmaster162 keepalived]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs {
notification_email {
18500777133@sina.cn
}
notification_email_from Alexandre.Cassen@firewall.loc
router_id lvs1
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.22.251
}
} virtual_server 172.16.22.251 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP real_server 172.16.22.134 3306 {
MISC_CHECK {
misc_path "/etc/keepalived/check_alive.sh 172.16.22.134"
misc_dynamic
}
}
real_server 172.16.22.142 3306 {
MISC_CHECK {
misc_path "/etc/keepalived/check_alive.sh 172.16.22.142"
misc_dynamic
}
}
}

然后是172.16.22.163的

[root@lvsbackup163 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs {
notification_email {
18500777133@sina.cn
}
notification_email_from Alexandre.Cassen@firewall.loc
router_id lvs2
} vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.22.251
}
} virtual_server 172.16.22.251 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP real_server 172.16.22.134 3306 {
MISC_CHECK {
misc_path "/etc/keepalived/check_alive.sh 172.16.22.134"
misc_dynamic
}
}
real_server 172.16.22.142 3306 {
MISC_CHECK {
misc_path "/etc/keepalived/check_alive.sh 172.16.22.142"
misc_dynamic
}
}
}

这里说说MISC_CHECK的配置

misc_path里面指定的脚本需要返回值的,不同的返回值决定了RS是否健康。

  1. exit 0:健康检查正常,keepalived状态正常。
  2. exit 1:检测失败,keepalived 状态异常。

这里贴下脚本/etc/keepalived/check_alive.sh的内容,顺便说说脚本的思路。

监控项:

Seconds_Behind_Master: 表示slave上SQL thread与IO thread之间的延迟。

Slave_IO_Running: IO线程的是否正常运行。

Slave_SQL_Running: SQL线程是否正常运行。

脚本思路如下:

  1. 通过mysql命令远程对目标服务器执行show slave status\G。然后把输出结果获取。
  2. 通过grep命令匹配输出结果。首先匹配“Slave_IO_Running: Yes”,匹配成功设置标志位f为0,否则退出。
  3. 通过grep命令匹配输出结果。第二匹配“Slave_SQL_Running: Yes”,匹配成功设置标志位f为0,否则退出。
  4. 通过grep命令匹配输出结果,最后匹配“Seconds_Behind_Master: [0-9]*”,如果超过设定时间,那么退出,否则如果三个匹配都匹配上了,那么就说明RS服务正常。

脚本内容

[root@lvsbackup163 ~]# cat /etc/keepalived/check_alive.sh
#!/bin/bash
user='root';
passwd='123456';
command='show slave status\G;'
port=3306 rt=`mysql -u$user -p$passwd -h $1 -e "$command" `
echo $rt | grep -e "Slave_IO_Running: Yes" -o >/dev/null 2>&1
if [ $? -ne 0 ];then
exit 1
else
f1="0"
fi
echo $rt | grep -e "Slave_SQL_Running: Yes" -o >/dev/null 2>&1
if [ $? -ne 0 ];then
exit 1
else
f2="0"
fi
behind_time=`echo $rt | grep -e "Seconds_Behind_Master: [0-9]* " -o|awk '{print $2}'`
if [ $behind_time -ge 120 ];then
exit 1;
elif [ $f1 -eq 0 -a $f2 -eq 0 ];then
exit 0
fi

记得脚本赋值777的权限

[root@lvsmaster162 keepalived]# chmod 777 /etc/keepalived/check_alive.sh

两端都启动keepalived

[root@lvsmaster162 keepalived]# service  keepalived start

[root@lvsmaster162 keepalived]# ip a|grep 'inet '   # master端上有VIP了,启动成功
inet 127.0.0.1/8 scope host lo
inet 172.16.22.162/24 brd 172.16.22.255 scope global eth0
inet 172.16.22.251/32 scope global eth0

此时我们再看看ipvsadm调度情况

[root@lvsmaster162 keepalived]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.22.251:3306 rr persistent 50
-> 172.16.22.134:3306 Route 1 0 0
-> 172.16.22.142:3306 Route 1 0 0
配置RS(两台sql slave)

两台RS服务器一模一样的配置。

我们使用的LVS-DR模式,所以需要在RS配置VIP,以及更改arp的响应模式,LVS-DR模式原理流程请看我的另一篇博客:http://www.cnblogs.com/liaojiafa/p/6059652.html

[root@dbrepslave134 ~]# ifconfig lo:0 172.16.22.251 netmask 255.255.255.255 broadcast 172.16.22.251
[root@dbrepslave134 ~]# route add -host 172.16.22.251 dev lo:0
[root@dbrepslave142 ~]# tail /etc/sysctl.conf
'''''
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
[root@dbrepslave142 ~]# sysctl -p # 启用刚才的新添加在sysct.conf配置

个人建议不要忘记在rc.local里面写入增加VIP的添加命令,省去开机后人工配置的麻烦:

[root@dbrepslave142 ~]# cat /etc/rc.local
ifconfig lo:0 172.16.22.251 netmask 255.255.255.255 broadcast 172.16.22.251
route add -host 172.16.22.251 dev lo:0

检测LVS-keepalived是否能够正常切换如果master宕机后。

我们拿一台mysql-client(172.16.160.191)来测试,

[root@lvsmaster191 ~]# mysql -uroot -p123456 -h172.16.22.251
mysql> show databases # 登陆成功,命令执行正确
+--------------------+
| Database |
+--------------------+
| information_schema |
| hello |
| mysql |
| test |
+--------------------+
4 rows in set (0.15 sec)

查看lvs-keepalived-master(172.16.22.162)状态

[root@bogon ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.22.251:3306 rr persistent 50
-> 172.16.22.134:3306 Route 1 1 0
-> 172.16.22.142:3306 Route 1 2 0

下面我们关闭keepalived-master。模拟keepalived-master宕机,

[root@bogon ~]# ip a|grep 'inet '
inet 127.0.0.1/8 scope host lo
inet 172.16.22.162/24 brd 172.16.22.255 scope global eth0
inet 172.16.22.251/32 scope global eth0
[root@bogon ~]# halt

查看keepalived-backup(172.16.22.163)的状态

[root@lvsbackup163 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.22.251:3306 rr persistent 50
-> 172.16.22.134:3306 Route 1 0 0
-> 172.16.22.142:3306 Route 1 0 0
[root@lvsbackup163 ~]# ip a|grep 'inet '
inet 127.0.0.1/8 scope host lo
inet 172.16.22.163/24 brd 172.16.22.255 scope global eth0
inet 172.16.22.251/32 scope global eth0

再在客户端上查看

mysql> use hello;  #没有报错,正常使用

检测RS宕机后LVS是否能够正常剔除服务。

模拟服务宕机

在172.16.22.134上关闭数据库

[root@dbrepslave134 ~]# service  mysqld stop
Stopping mysqld: [ OK ]

在LVS-keepalived-master上看lvs负载状态:

[root@lvsmaster162 ~]# ipvsadm -Lm
Illegal 'forwarding-method' option with the 'list' command
[root@lvsmaster162 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.22.251:3306 rr persistent 50
-> 172.16.22.142:3306 Route 1 0 0 # 已经把故障节点172.16.22.134提出服务了。

模拟主从不一致了

造成主从不一致的状态,很简单,

  1. 在Master上上创建一张表,然后插入数据后,确认此时在两者是同步状态。
  2. 我们在172.16.22.134删除我们刚才新建的那张表,然后再在DBMaster上向刚才新建的表插入数据,一插就完蛋了,主从不同步了,因为172.16.22.134没有这个表了,导致两者数据库不一致,所以不同步了。

    在172.16.22.134上查看当前状态
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.22.250
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysqld-bin.000019
Read_Master_Log_Pos: 788
Relay_Log_File: mysqld-relay-bin.000012
Relay_Log_Pos: 815
Relay_Master_Log_File: mysqld-bin.000019
Slave_IO_Running: Yes
Slave_SQL_Running: No # IO线程不行了,因为缺少库

我们在LVSmaster上查看状态:

[root@lvsmaster162 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.22.251:3306 rr persistent 50
-> 172.16.22.142:3306 Route 1 0 0 # 检测到134有问题,主从不同步了,剔除了服务。

至此,我们LVS+Keepalived+Mysql-Slave已经能够正常工作了。到此我们这套架构已经可以正常工作了。

Mysql+heartbeat+DRBD 作用于 Mysql写操作。

Lvs+keepalived+Mysql(Slave)作用于Mysql读操作。

高可用Slave集群的一些注意点。

  1. LVS有多种负载算法,采用DR模式是LVS发挥最大性能,
  2. 当Slave增加很多时候,超过10台以上建议通过垂直拆分来解决压力问题。因为后端RS健康检测是脚本定义的,性能问题会导致LVS机器负载过高。
  3. 目前DR模式在一个广播域(LAN)中部署。不能够实现多IDC容灾问题,IDC容灾问题需要另行考虑。

部署Mysql集群需要考虑的问题。

我们这个方案需要考虑以下几个问题:

  1. heartbeat+DRBD+MySql这个方案不能够实现毫秒级别切换速度,他的切换速度主要受两个因素影响:文件系统和表的恢复需要时间。这里需要说明的是,MyISAM引擎不适合做HA,因为MyISAM类型的表在宕机后需要 很长的修复时间,这违背了HA的初衷,所以把除系统表之外的所有表类型都修改为innodb引擎。
  2. 如果对可靠性要求比较高。写入的并发量非常大的时候,建议在my.cnf中修改“innodb_flush_log_at_trx_commit = 1”,以保证事务的安全性。但是这对I/O提出挑战。如何抉择,最终需要根据情况具体做出权衡。
  3. 如果写入量不大,可以考虑在my.cnf中加入"sync_bing = 0"来避免在某种特殊情况下Master突然宕机,出现Slave上关于Master的binlog位置(master_log_pos)点超于master宕机时写入的binlog点的情况。这对I/O很有挑战性。
  4. 在Slave上变更主库连接信息时,最好指定“Master_connect_retry”的值为一个合适的数值。在出现VIP漂移的时候,Slave可以更快的去重新连接VIP,避免因为切换master造成同步延迟的问题。
  5. 要为my.cnf中的“innodb_log_file_size”的“innodb_log_buffer_size”参数设置合适的值,设置太大会导致恢复时间比较长,降低故障切换的速度。
  6. 建议在ha.cf中使用“auto_failback off”选项,如果使用“on”选项会导致主备机之间来回切换,增加成本。
  7. 使用dopd保证在数据不一致时不进行切换,需要人工干预,同时要对drbd的同步进行监控,不同步时报警通知DBA。
  8. 如果是OS是64位,建议使用/usr/lib64/heartbeat目录下的ipfail和dopd。
  9. 在使用非3306端口或多个端口运行一台物理机时,修改/etc/init.d/mysqld的脚本使其支持status,start,stop参数。虽然可以在一台主机上部署多个DRBD分区,但建议一台主机部署一个DRBD分区,一个端口。这样做资源有一定的浪费,但是管理成本低。不建议在一台服务器上部署多个DRBD分区和搭建多个MYSQL,例如/dev/drbd0(primary/Secondary),/dev/drbd1(Secondary/Primary),这种模式下减少了机器成本,但是增加了管理成本以及恢复的复杂度,同时违背了这个方案的初衷,便捷管理,故障后修复速度快。
  10. HA也有自己的适合场所,不能利用它解决所有问题(因为HA并不能监控Mysql的服务状态,当Mysql主节点的连接断开出现宕机时,HA默认监控不到),这时候需要通过heartbeat的crm模式来实现对Mysql端口或者服务的监控。CRM可以参考这位兄台的博客:http://blog.csdn.net/kobeyan/article/details/7587899
  11. 顶起检测Mysql服务和系统是否正常运行,小概率事件往往是导致大故障的根源。

4 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之Lvs为Mysql-slave做负载均衡的更多相关文章

  1. 3 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之heartbeat的搭建

    preface 在上节的说了mysql的搭建,这节我们在上节的基础上,继续搭建heartbeat. 安装和配置heartbeat 采用yum安装,dbmaster81和dbbackup136上都安装, ...

  2. 1 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之DRBD的搭建

    preface 近来公司利润上升,购买了10几台服务器,趁此机会,把mysql的主从同步的架构进一步扩展,为了适应日益增长的流量.针对mysql架构的扩展,先是咨询前辈,后和同事探讨,准备采用Mysq ...

  3. 5 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之生产环境下drbd裂脑处理

    preface 公司的业务变更,导致服务器要搬迁,所以需要关闭服务器,然后到新地在开启服务器. 关机前确定drbd+heartbeat+mysql是正常使用的,没有异常,Heartbeat和drbd都 ...

  4. 2 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之MySql的搭建

    preface 上一节我们讲了DRBD的原理,以及如何部署DRBD,那么现在在上一节的基础上部署Mysql 安装并启动Mysql 为了方便,我一般采用yum安装Mysql.命令如下: 在172.16. ...

  5. 【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Webserver集群

    额.博客名字有点长.. . 前言 最终到这篇文章了,心情是有点激动的. 由于这篇文章会集中曾经博客讲到的全部Nginx功能点.包含主要的负载均衡,还有动静分离技术再加上这篇文章的重点.通过Keepal ...

  6. LVS集群简介及使用

    什么是集群 一组通过高速网络互联的计算组,并以单一系统的模式加以管理 将很多服务器集中在一起,提供一种服务,在客户端看来就象是只有一个服务器 可以在付出较低成本的情况下获得在性能,可靠性,灵活性方面的 ...

  7. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之集群部署环境规划(一)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.环境规划 软件 版本 ...

  8. LVS+Heartbeat 高可用集群方案操作记录

    之前分别介绍了LVS基础知识和Heartbeat基础知识, 今天这里简单说下LVS+Heartbeat实现高可用web集群方案的操作说明. Heartbeat 项目是 Linux-HA 工程的一个组成 ...

  9. (转)基于keepalived搭建MySQL的高可用集群

    基于keepalived搭建MySQL的高可用集群  原文:http://www.cnblogs.com/ivictor/p/5522383.html MySQL的高可用方案一般有如下几种: keep ...

随机推荐

  1. .Net相关

    Lucene 全文搜索 http://lucenenet.apache.org/ Memcached 分布式缓存 http://memcached.org/ selenium UI自动化测试 http ...

  2. IIS——发布网站

    当我们要上线一个网站时,不要把整个项目原封不动的发布到服务器,而要经过右键发布后,然后再将发布的文件路径配置到IIS~ 详细信息见链接:http://www.52ij.com/jishu/aspx/1 ...

  3. Oracle sql develpoer

    Oracle SQL Developer是针对Oracle数据库的交互式开发环境(IDE)     Oracle SQL Developer简化了Oracle数据库的开发和管理. SQL Develo ...

  4. ECharts图表中级入门之formatter:夜谈关于ECharts图表内的数据格式化方法

    来源于:http://www.ithao123.cn/content-3751220.html 格式化之所以存在,主要是因为我们想把一些不够人性化的内容通过某种处理让其变得人性化,便于用户更好地理解内 ...

  5. android之二维码扫描的实现

    二维码扫描引擎有 ZBar 和ZXing 一. 使用开源ZXing扫描的缺点 1.原始代码是横屏模式,尽管可以改成竖屏,但是扫描界面的自定义和多屏幕适配不好做 2.有效扫描区域不好控制,可能是我自己技 ...

  6. Java设计模式(七) 模板模式

    [模板模式]在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 1,定义模板类 package com.pattern ...

  7. 转: linux内核版本本地版本号的检查——setlocalversion

    转载:http://blog.csdn.net/adaptiver/article/details/7225980 1.   引子 编译2.6.35.7 kernel版本的时候发现,"2.6 ...

  8. EPUBBuilder编辑器新版

    epub全称为Electronic Publication的缩写,意为:电子出版, epub于2007年9月成为国际数位出版论坛(IDPF)的正式标准,以取代旧的开放Open eBook电子书标准,e ...

  9. 【收藏】Android AutoLayout全新的适配方式, 堪称适配终结者

    来源:http://blog.csdn.net/lmj623565791/article/details/49990941 更多:Android屏幕适配全攻略(最权威的Google官方适配指导) 一. ...

  10. 类-string/Manth/Random/DateTime-及练习

    类一.string类:.Length 字符串的长度 .Trim() 去掉开头以及结尾的空格.TrimStart() 去掉开头的空格.TrimEnd() 去掉结尾的空格 .ToLower() 全部转换为 ...