你好,我是悟空。
本篇主要内容如下:
目录
背景
我们的项目采用了读写分离的方案:查询和更新的业务走主库,统计相关的功能走从库,从而减少主库的压力。原理如下图所示:
读写分离的方案
如果从库崩了,实在无法访问了,就会把所有请求打到主库上。原理如下图所示:
从节点崩了,部分流量打到主节点
但是最近遇到一个问题,MySQL 从节点上的服务无缘无故的崩了,查看日志也找不到什么端倪。
为了保证从节点的可用性,我们使用了 Keepalived 软件来监测从节点存活状态,如果从节点崩了,则自动重启 MySQL 容器。
本篇将会讲解没什么卵用的排查记录,以及如何保证从节点可用性,注意,还不是完全的高可用。
一、排查记录
虽说没有找到 MySQL 从节点容器真正崩了的原因,但是这排查记录还是得记录下。
1.1 查看 MySQL 的容器日志
2023-02-08 6:27:30 开始 Shutdown 了,没有提示为什么 shutdown。
2023-02-08 6:27:34 Shutdown 完成。
1.2 查看 MySQL 的错误日志
可以看到 6:27:30 没有异常日志。
这不就尴尬了,完全不知道为啥崩了。
(备注:另外也可以看下容器的信息,docker inspect <容器 id>,会显示容器什么时候启动和停止的。)
二、怎么理解读写分离
读写分离有个限制条件就是主库可以用来做读写,从库实时同步主库数据,而且从库是只读的。
我们的项目中有统计功能就是连接从库查询数据,从库不会进行数据更新的操作。
读写分离我认为可以分为两种:
- 1、完全的读写分离:主库只用来更新数据,从库只用来查询数据。
- 2、部分读写分离:主库既可以用来读数据,又可以进行查数据;从库作为只读的备库,分担耗性能的查询工作。
我们项目采用的是第二种方案,涉及到 I/O 密集型的查询工作就交给 MySQL 从库去处理。
部分读写分离
三、从节点的高可用如何保证?
3.1 保证从节点的可用性
采用 keepalived 自动检测 MySQL 服务是否正常,如果不正常,自动重启 MySQL 容器。
提高从节点的可用性
3.2 从节点数据库无法重启了怎么办?
目前从节点只有一个节点,如果从节点崩了,从哪执行查询?
有两种方案:
- 方案一:读操作切换到主库去查询。带来的问题:主库的压力会很大。
- 方案二:部署两个从节点,从节点之间相互同步数据,只有一个从节点提供服务,另外一个节点作为备用从库,前者崩了的话,流量自动切换到后者。(需要两个节点开启 Keepalived 来提供流量切换的能力)带来的问题:部署的复杂性,主从同步延迟。
目前我们采用的是第一种方案,如果从节点崩了,读操作会切换到主库上去执行。所以保证从节点不崩就很重要了。
四、实践:保证从节点的可用性
这次我们要做的就是在在从节点开启 Keepalived,以及修改重启 MySQL 的脚本。从节点的 Keepalived 的 VIP 地址和主节点的 Keepalived 的 VIP 不一样。
原理如下所示:
从节点首先得安装和配置 keepalived 在之前的文章中已经详细讲解过了。
我在讲解主主切换的文章中提到过 keepalived 承担的职责是就是监测 MySQL 服务是否正常,如果不正常,则重启 MySQL,如果重启失败,则退出 keepalived,自动将流量切换到另外一个节点。
这次的从节点只作为备库,没有切换到主库的要求,所以在主库宕机后,不需要接管读写的流量。
4.1 启动 keeaplived 服务以及开机自启动
安装好 keepalived 之后,执行以下命令启动。
启动 keeaplived 服务
还需要设置 keepalived 开机自启动。
具体内容可以看这篇实战 MySQL 高可用架构
实战 MySQL 高可用架构目录
4.2 如何监测 MySQL 服务的健康状况
keepalived 配置文件中定时监测 MySQL 服务的健康状况。
修改配置文件:
4.3 如何自动重启 MySQL 服务
自动重启 MySQL 的脚本之前也讲解过,这里再贴一下。当 keepalived 检测到 MySQL 无法连接时,就自动重启 MySQL 容器。
如何自动重启 MySQL 服务
4.3 如何不让 Keepalived 切换流量到其他机器
因为主节点也是开启了 Keepalived,如果主从的 Keepalived 的 VIP 都是同一个(之前配置的是 192.168.56.88),那么如果主节点崩了,就会将流量自动切换到从节点,因为我们这个从节点只作为备库,不需要它升级为主库,所以可以将主从节点的 Keepalived 的 VIP 设置为不一样,这样的话,从节点就不会升级为主节点。
这里我们就把之前的 VIP 192.168.56.88 改为 192.168.56.89。
修改配置文件:
如何自动重启 MySQL 服务
同时重启脚本中,有一行命令是强制退出 keepalived(killall keepalived),这行命令可以让 Keepalived 就有将流量切换到其他机器的能力。如果让 keepalived 强制退出,则会将流量切换到另外一台 keepalived 还存活的机器上。
这里不需要切换,就可以注释掉这行命令。
五、总结
我们项目采用了数据库读写分离的模式,但是没有对从节点做高可用,所以也遇到从节点不能提供服务的问题。
本篇通过一次 MySQL 从节点崩了的事件,引出了如何对从节点做高可用,然后从实践的角度详细讲解了如何去配置 keepalived 来保证从节点的高可用。
后续:如何让项目实现读写分离?
关于我
8 年互联网开发经验,擅长微服务、分布式、架构设计。目前在一家大型上市公司从事基础架构和性能优化工作。
InfoQ 签约作者、蓝桥签约作者、阿里云专家博主、51CTO 红人。
本文转载自微信公众号「 悟空聊架构」,可以通过以下二维码关注。转载本文请联系悟空聊架构公众号。