照例,本篇文章以上篇为基础:
linux实现TimescaleDB 基于异步流的主从复制(四)
其实,上一篇文章结束,就已经对高可用配置的差不多了,但是在测试时,我发现,当主机挂了,keepalived切换到从机,从机的数据库(redis和timescale)不能写入数据,是只读的。当使用配置文件修改它不只是只读后,从机数据库确实可以存放数据了,但是当主机重启,keepalived切换到主机,从机在这段时间内添加的数据却不能复制到主机。
经过多方查阅,好吧,官网随便一翻就翻到了,这里是缺少个sentinel,即哨兵。只要把哨兵配上,就好了。
sentinel,中文名哨兵,是实现redis主从复制高可用的一个可靠的解决方案。他的原理是,当主机宕机后,从机的redis数据库,会被sentinel选举为master数据库,当主机重启后,主机的redis数据库只会是slave,只读模式,并复制从机上的master数据库。
中文官网:redis sentinel官方中文文档
本文章是基于,已经配置好redis主从复制,然后在此基础上,实现高可用。
如果没有配置好redis的主从复制,请参考:
Linux系统的keepalived+tomcat+redis+other的高可用实现(一)中的第四章内容。
sentinel在sentinel2版本之后,内嵌到了redis中,所以我们需要在一台机器上启动两个redis容器,一个作为redis容器,一个作为sentinel容器。
然后修改sentinel.conf配置文件,将配置文件挂载到sentinel容器内部,生成容器,即可实现sentinel的监控。
主要参考该篇文章配置:Docker搭建Redis一主两从三哨兵;
提供了坚实的理论基础:Redis哨兵模式(sentinel)学习总结及部署记录(主从复制、读写分离、主从切换);
解决了不能监测到从机的问题:redis sentinel不能监测到slave,master宕机后不能主从切换。
CentOS7,主机:192.168.50.34,备机:192.168.50.31
本实验为一主一从二哨兵,而不是主流的一主二从三哨兵。
进入/data/redis
文件夹,当然,随便哪个都可以,这个无所谓。
运行命令:
wget http://download.redis.io/redis-stable/sentinel.conf
即可下载sentinel.conf配置文件。
同时,这里贴上下载redis.conf配置文件的方法(这里不需要):
wget http://download.redis.io/redis-stable/redis.conf
(1)将daemonize属性修改为yes
daemonize yes
(2)添加日志文件地址,此地址为容器内部地址。
logfile "/var/log/redis/sentinel.log"
(3)添加:
sentinel monitor mymaster master的ip地址 6379 1
注意:sentinel会自动更改你的配置文件,ip地址会自动更改为master的地址。可以预先填为主机地址,即我的为192.168.50.34.当主机的redis挂掉后,这个地址会自动变为从机的ip地址。
6379
为redis的端口号。
1
为需要至少几个sentinel同意,才能切换master。一般为sentinel集群个数的一半加一。例如,一主二从三哨兵,此值为2,一主一从二哨兵,此值为1.
(4)添加
sentinel auth-pass mymaster 123456789
mymaster
为master-name,即和第(3)条配置文件对应。
123456789
为密码,主从机需一致,需要与redis配置中的密码一致,当然,redis中未配置密码,只需主从密码一致即可。
该条配置解决了sentinel检测不到从机的问题。
在此之前,要先启动redis容器,注意此时的redis容器以及配置好了主从复制。
docker run -it --name sentinel -p 26379:26379 -v /data/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf -d hub.c.163.com/library/redis /bin/bash
解释:
--name sentinel
:容器命名
-p 26379:26379
:挂载端口;
-v /data/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf
:挂载配置文件,容器外:容器内;
-d
:后台运行;
hub.c.163.com/library/redis
:镜像名;
/bin/bash
:运行文件;
一般情况下,将主机的sentinel.conf文件复制到从机,即可自动改变文件内的ip地址。
配置文件内容无须修改。
由3步骤可看,我们生成的只是一个redis容器,那么如何启动该容器内部的sentinel呢?
docker exec -it sentinel bash
mkdir /var/log/redis
touch /var/log/redis/sentinel.log
redis-sentinel /usr/local/etc/redis/sentinel.conf
apt-get update
apt-get install vim
vim sentinel.conf
显示+monitor,即为检测到主机,显示+slave,即为检测到从机。
查看容器外部的sentinel.conf配置文件,在末尾,会发现,sentinel会自动为该文件添加:
sentinel known-replica mymaster 192.168.50.31 6379
表示:slave从机31复制主机。
进入可视化界面,分别连接主从服务——[先启动redis容器,再启动sentinel容器]。
redis容器(以下宕掉以及重启的都为redis容器):
宕掉主机,往从机添加数据,添加成功。
启动主机,主机复制从机的数据。
宕掉从机,往主机添加数据,添加成功。
启动从机,从机复制主机的数据。
sentinel容器:
宕掉主机的sentinel,两个redis数据库正常使用,
接着宕掉主机的redis容器,往从机添加数据,添加成功,
启动主机的redis容器,复制数据成功。
重启sentinel容器,进入容器内部启动sentinel,redis-sentinel /usr/local/etc/redis/sentinel.conf
注意: 主备切换,可能会有10s左右延迟。
解决方案:
通过java代码,调用sentinel接口:
redis哨兵模式-sentinel ,java客户端动态切换master
通过配置VIP切换脚本文件:
搭建一个redis高可用系统
该日志为,启动主机,宕掉主机,启动主机,宕掉从机,启动从机,所产生的日志文件。
因目前懒得看,所以暂存下来,以备后用。
主机日志文件:
从机日志文件: