我们的项目采用了读写分离的方案:查询和更新的业务走主库,统计相关的功能走从库,从而减少主库的压力。原理如下图所示:
读写分离的方案
如果从库崩了,实在无法访问了,就会把所有请求打到主库上。原理如下图所示:
添加描述
从节点崩了,部分流量打到主节点
但是最近遇到一个问题,MySQL 从节点上的服务无缘无故的崩了,查看日志也找不到什么端倪。
为了保证从节点的可用性,我们使用了 Keepalived 软件来监测从节点存活状态,如果从节点崩了,则自动重启 MySQL 容器。
本篇将会讲解没什么卵用的排查记录,以及如何保证从节点可用性,注意,还不是完全的高可用。
虽说没有找到 MySQL 从节点容器真正崩了的原因,但是这排查记录还是得记录下。
docker logs 043 --tail 200
2023-02-08 6:27:30 开始 Shutdown 了,没有提示为什么 shutdown。
添加描述
2023-02-08 6:27:34 Shutdown 完成。
添加描述
cat /var/log/mysql/error.log
这个路径在 my.cnf 配置。
添加描述
可以看到 6:27:30 没有异常日志。
这不就尴尬了,完全不知道为啥崩了。
(备注:另外也可以看下容器的信息,docker inspect <容器 id>,会显示容器什么时候启动和停止的。)
读写分离有个限制条件就是主库可以用来做读写,从库实时同步主库数据,而且从库是只读的。
我们的项目中有统计功能就是连接从库查询数据,从库不会进行数据更新的操作。
读写分离我认为可以分为两种:
我们项目采用的是第二种方案,涉及到 I/O 密集型的查询工作就交给 MySQL 从库去处理。
添加描述
部分读写分离
采用 keepalived 自动检测 MySQL 服务是否正常,如果不正常,自动重启 MySQL 容器。
添加描述
提高从节点的可用性
目前从节点只有一个节点,如果从节点崩了,从哪执行查询?
有两种方案:
目前我们采用的是第一种方案,如果从节点崩了,读操作会切换到主库上去执行。所以保证从节点不崩就很重要了。
添加描述
这次我们要做的就是在在从节点开启 Keepalived,以及修改重启 MySQL 的脚本。从节点的 Keepalived 的 VIP 地址和主节点的 Keepalived 的 VIP 不一样。
原理如下所示:
添加描述
从节点首先得安装和配置 keepalived 在之前的文章中已经详细讲解过了。
我在讲解主主切换的文章中提到过 keepalived 承担的职责是就是监测 MySQL 服务是否正常,如果不正常,则重启 MySQL,如果重启失败,则退出 keepalived,自动将流量切换到另外一个节点。
这次的从节点只作为备库,没有切换到主库的要求,所以在主库宕机后,不需要接管读写的流量。
安装好 keepalived 之后,执行以下命令启动。
systemctl start keepalived
添加描述
启动 keeaplived 服务
还需要设置 keepalived 开机自启动。
sudo vim /etc/rc.local
添加以下命令
systemctl start keepalived
keepalived 配置文件中定时监测 MySQL 服务的健康状况。
修改配置文件:
sudo vim /etc/keepalived/keepalived.conf
添加描述
自动重启 MySQL 的脚本之前也讲解过,这里再贴一下。当 keepalived 检测到 MySQL 无法连接时,就自动重启 MySQL 容器。
添加描述
如何自动重启 MySQL 服务
因为主节点也是开启了 Keepalived,如果主从的 Keepalived 的 VIP 都是同一个(之前配置的是 192.168.56.88),那么如果主节点崩了,就会将流量自动切换到从节点,因为我们这个从节点只作为备库,不需要它升级为主库,所以可以将主从节点的 Keepalived 的 VIP 设置为不一样,这样的话,从节点就不会升级为主节点。
这里我们就把之前的 VIP 192.168.56.88 改为 192.168.56.89。
修改配置文件:
sudo vim /etc/keepalived/keepalived.conf
添加描述
如何自动重启 MySQL 服务
同时重启脚本中,有一行命令是强制退出 keepalived(killall keepalived),这行命令可以让 Keepalived 就有将流量切换到其他机器的能力。如果让 keepalived 强制退出,则会将流量切换到另外一台 keepalived 还存活的机器上。
这里不需要切换,就可以注释掉这行命令。
我们项目采用了数据库读写分离的模式,但是没有对从节点做高可用,所以也遇到从节点不能提供服务的问题。
本篇通过一次 MySQL 从节点崩了的事件,引出了如何对从节点做高可用,然后从实践的角度详细讲解了如何去配置 keepalived 来保证从节点的高可用。
后续:如何让项目实现读写分离?
我正在参与 腾讯云开发者社区数据库专题有奖征文。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。