阅读原文请点击
摘要:部署一对MySQL主备的数据库是很容易的,但是这两台数据库如何变为‘一台‘对外输出呢? 也就是说,我的代码里面只可能写一个IP对数据库访问,不可能两个都写,如果说主库挂掉了,我要这备库有何用? 我们来看下,如何通过Keepalived,去解决这个问题。
首先我们来看一下通过Keepalived实现,需要对MySQL有什么要求
MySQL需要采用MM复制结构,也就是master-master。当一台为主库的时候,备库开启只读模式(set global read_only=1)
然后我们来看一下数据库在不同情况下,切换是如何进行的:
MySQL切换无非两种,一种是人为切换,一种是天灾。也就是一种是正常切换一种是异常切换。
正常切换
正常切换是指主库能正常访问 切换的时候保证主备数据库一致
正常切换的流程
1 主库设置只读 kill主库进程
2 备库上等待主库将所有binlog都已经传过来 并且binlog执行完成
3 备库上关闭只读模式(set global read_only=0)
上面步骤任何步骤失败 则切换失败 在有些情况下 无法将主库设置成只读 则备库延迟时间太长 则无法进行正常的主备切换
异常切换
异常切换是指主库发生异常 无法连接到主库的情况
异常切换的情况下 无法保证数据严格一致 有几种方式保证主备库数据尽可能一致
1 已经传输到备库的binlog必须执行完成
2 主库开启心跳 定期更新一跳心跳记录 备库上查看心跳记录的时间戳和系统当前时间的差异 如果差异超过一定时间 则不能切换到主库
主库切换之后 还需要将应用程序的数据库切换备库,可以通过以下途径来实现切换:
1 手动修改应用配置
2 使用dns 主备切换后 将dns指向新的主库
3 使用VIP
手动修改数据库连接配置显然不是很好的办法 修改时间不可控
dns切换避免了上面这些问题
而是用Keepalived,就可以解决主库挂掉之后,我的代码找不到目的地的情况。其实就是给了这两台数据库一个IP,供大家访问
工作原理:VRRP(vritual router redundancy protocol)虚拟路由冗余协议
vrrp路由器是指运行的vrrp路由器是物理实体 虚拟路由器是指vrrp协议创建的 是逻辑概念
一组vrrp路由协同工作共同构成一台虚拟路由器 vrrp中存在一种选举机制 用以选出提供服务的路由 即主控路由 其他则成了备份路由 当主控路由失效后 备份路由中会重新选举出一个主控路由来继续工作 来保障不间断
keepalived原理:
keepalived安装在两台物理服务器上 并互相监控对方是否正常运行
当A工作正常的时候 会将VIP对应的MAC地址为节点A网卡的MAC地址
当A发生故障的时候 节点B上的keepalived会检测到 并将VIP的MAC等于B的MAC地址
Keepalived的部署比较容易,直接可以yum 安装,主要的就是他的参数文件,参数文件是如何控制主备的。
vrrp_script chk_port_3306 {
script "/opt/dtstack/dtagent/agent/mysqlha_check_alive.py 3306"
interval 11 # check every 2 seconds
fall 3 # require 2 failures for KO
rise 3 # require 2 successes for OK
timeout 11
}
先看第一部分,检测系统上3306端口,监控的途径是通过/opt/dtstack/dtagent/agent/mysqlha_check_alive.py 3306这条命令来判断的,就是判断系统3306端口是否存在,如果你的MySQL是别的端口,那么就需要作下更改,脚本是一大神写的,就不贴出来了。
如果一台机器上起着多个MySQL端口,也可以多些一部分,缺检测不同端口是否存活。
vrrp_instance mysql_3306 {
state MASTER
interface eth0 #检测eth0
garp_master_delay 5
virtual_router_id 231 #路由组
priority 251 #权重
advert_int 1
再来看第二部分,这一部分主要决定的你这台机器上的3306端口是否是主库,而且这台机器的外网是不是eth0网卡上。virtual_router_id这个参数主库跟备库必须要一样,这样告知Keepalived他需要看到是那一个路由组的机器。priority权重约大,那么主库的方向就越往哪台机器上偏。
authentication {
auth_type PASS
auth_pass PASS3306
}
virtual_ipaddress {
192.168.40.231/24 dev eth0 # vip是192.168.40.231/24 起在eth0上
}
track_script {
chk_port_3306 # 检测3306端口
}
然后看第三部分,这一部分就是实现2变1的地方,起一个vip到eth0网卡上,当某台数据库为主库的时候,那么这个vip就会票到这个台机器的eth0网卡上。
最后一部分就是debug的地方了,就不详细说明了。
部署完Keepalived,然后修改完对应的参数文件后,我们启用VIP
启动Keepalived
[root@iZ25u0bag2mZ ~]service keepalived start
使用脚本测试是否成功
[root@iZ25u0bag2mZ ~]/opt/dtstack/dtagent/agent/mysqlha_check_alive.py 3306
check_read
check_read: {'data': (1L,), 'success': 1}
然后我们查看一下主库的IP上是否飘着我们的VIP
[root@iZ25u0bag2mZ ~]ip a
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether fa:16:3e:71:75:2f brd ff:ff:ff:ff:ff:ff
inet 192.168.40.32/24 brd 192.168.40.255 scope global eth0
inet 192.168.40.231/24 scope global secondary eth0
inet6 fe80::f816:3eff:fe71:752f/64 scope link
valid_lft forever preferred_lft forever
可以看到eth0网卡上起着2个IP,一个是本机IP,另一个就是VIP,这时候,我们就可以通过这个VIP对我们的MySQL数据进行访问了。