keepalived是如何实现MySQL高可用的?
首先我们来看一下通过 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: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 数据进行访问了。
来源: https://yq.aliyun.com/articles/175040