docker redis的哨兵模式搭建——遇坑笔记

背景

此次用阿里云服务器,docker-compose 搭建redis集群和sentinel集群。(一主两从,三台哨兵)

想着使用docker搭建一个简单的redis 主从 + 哨兵集群,但我刚开始对于docker不太了解,又没能找到一个完整的且能够清晰的说明哨兵与哨兵之间,主从之间的通信问题以及网络问题的博客,导致浪费了太多时间在错误的配置文件上。后面补及docker知识后,在此记录下这次遇到的坑。

本次搭建集群的目的:

  1. 本地能通过redis manager连接搭建的redis集群。
  2. 实现redis集群的高可用

坑一:由于不熟悉docker-compose命令导致的错误

使用docker-compose.yml配置redis集群和sentinel集群,当yml文件修改需重新构建docker容器时,需用 docker-compose up --force-recreate -d 命令。

–force-recreate:强制重建容器
-d: 后台运行方式

坑二:sentinel与redis集群通信的问题

情况1:当sentinel配置文件写的ip地址为master容器内部的地址且没有配置network时,sentinel无法监测主从节点,sentinel内部ping redis服务器会ping不通

在这里插入图片描述

sentinel日志信息也没发现主从节点

在这里插入图片描述
ps:其中+monitor master mymaster 172.20.0.4 6379 quorum 2这一行是根据sentinel.conf默认打印的,并不是代表监测到了master主节点,并且sentinel中也没有
+sentinel标识,即代表没有从主节点监测到其他sentinel。

所以目前只有1个哨兵,它发现主节点ping不通,所以是+sdown状态。(需要达到quorum票数 或者 哨兵节点/2+1票数才能变为+odown状态。目前整个哨兵群都各自发现不了对方,因为他们连不上主节点,无法从sentinel:hello频道获取其他sentinel信息)

+sentinel :一个监视给定主服务器的新 Sentinel 已经被识别并添加。

redis集群配置如此:

在这里插入图片描述
sentinel集群配置如此:(不指定network)

在这里插入图片描述
sentinel配置文件如此:(设置的master容器内部ip地址)

在这里插入图片描述
当进入sentinel容器内,使用命令访问从节点时候,返回空

在这里插入图片描述
访问主节点有返回,这是返回的sentinel的默认的主节点的信息

在这里插入图片描述
master和slave能连接

在这里插入图片描述
解释:这是由于redis主从节点和sentinel节点不再同一网段下。所以sentinel ping不了redis主节点。

在这里插入图片描述
情况二:当sentinel配置文件写的ip地址为宿主机的地址时,sentinel无法访问slave节点.。这种情况与情况一类似,配置文件就sentinel.conf 不一样(ip变了)

在这里插入图片描述
sentinel能监测到redis主从节点

在这里插入图片描述
master能和从节点连接。

在这里插入图片描述

ps:这里的ip由于测试重建了redis容器,导致docker分配了和之前不同的ip地址给redis主从节点。
这里的redis主节点ip地址由172.20.0.3变成了172.20.0.4,从节点ip为172.20.0.2和172.20.0.3。

sentinel容器内部获取slave节点时

在这里插入图片描述

ps:这代表sentinel无法监测到slave节点,无法得知它是否连上master节点以及master的相关信息。但是还是能显示其他信息的,例如从节点的ip,端口,角色等等。因为这些信息是从master主节点通过info命令获取到的。

坑二总结:

由于redis集群与sentinel之间是在不同docker容器的,而不同容器间的网桥是不同的,导致他们无法访问。集群间能互相访问是因为由docker-compose.yml编排的容器,他们默认分配在同一网段下,所以他们能互相通信。例如上面的sentinel之间也能相互ping通。

使用命令查看docker网络情况可知,redis集群和sentinel集群都各自在独立的网桥下。当使用docker-compose编排文件启动容器时,会默认配置各容器在同一桥接网络下,默认取名为第一个容器的名称+_default.

各桥接网络情况

各桥接网络情况

sentinel集群都在172.21.0.0网段下

在这里插入图片描述

到此:我们只要解决这两个问题,就能实现redis的哨兵模式集群,并能外部访问了

  1. 让sentinel集群和redis集群在同一网桥下,为了sentinel能访问每个redis节点。
  2. sentinel.conf中配置宿主机ip地址。

关于第2点的解释:

因为本地redis manager是要通过连接sentinel的26379端口,来连接redis集群的。因为本地访问sentinel时,它是会返回sentinel配置文件中的master的ip和端口,这也是为什么sentinel配置的是宿主机ip地址。
而sentinel的配置文件是根据当前监测情况动态变化的,所以当从节点上升为主节点时,sentinel能返回正确的master地址给客户端。

正确的配置如下:(此处修改了master的端口为6380,slave端口为6381、6382)

redis集群配置文件:

在这里插入图片描述
sentinel集群配置如下

在这里插入图片描述
sentinel.conf配置文件如下,复制3份

在这里插入图片描述
可以看到redis集群配置文件多了replica-announce-ip,以及replica-announce-port

  • replica-announce-ip:指定slave向master节点发送的ip信息
  • replica-announce-port:指定slave向master节点发送的port信息

使用这两个参数后,从节点发送给主节点的ip和端口信息就是这里设定好了

ps:这里这么配置是因为sentinel是通过向master发送INFO命令获取所有从服务器的信息,这里获取到的是宿主机ip。而由于我们要本地客户端连接docker的redis,为了主从切换时sentinel获取到外网能访问的ip地址,所以这里指定了宿主机ip地址和端口。

sentinel也有类似的配置:

  • sentinel announce-ip
  • sentinel announce-port

启动后,进入master节点可以看到slave显示的ip信息是宿主机ip

在这里插入图片描述
但实际上从服务器的本身的地址还是容器虚拟地址172.x.x.x。

我们知道docker在运行容器时,容器内部有一个独立的网络(默认情况下),通过docker设置的虚拟网桥与外部通信。并且我们可以使用-p参数来映射docker容器的端口。docker使用的是一种类似端口映射的技术,这导致容器内外的ip和端口可能是不一样。而redis主从节点间通信时,是基于INFO命令的信息来自动发现从节点的ip和端口信息。

集群搭建总结:

1.主从服务器之间的通信是基于INFO命令的获取到的ip和端口信息。
2.哨兵与主服务器的通信是通过ping命令监测主服务器是否下线的。一个有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
3.哨兵与从服务器通信是通过向主服务器发送INFO命令获取到从服务器的ip和端口信息的。
4.Sentinel 可以通过发布与订阅功能来自动发现正在监视相同主服务器的其他 Sentinel , 这一功能是通过向频道 sentinel:hello 发送信息来实现的。

关于sentinel

每个 Sentinel 都需要定期执行的任务

  • 每个 Sentinel 以每秒钟一次的频率向它所知的主服务器、从服务器以及其他 Sentinel 实例发送一个 PING 命令。
  • 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。 一个有效回复可以是: +PONG 、 -LOADING 或者
    -MASTERDOWN 。
  • 如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态。
  • 如果一个主服务器被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
  • 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。 当一个主服务器被 Sentinel 标记为客观下线时, Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率会从
    10 秒一次改为每秒一次。
  • 当没有足够数量的 Sentinel 同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的 PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。

自动发现 Sentinel 和从服务器

一个 Sentinel 可以与其他多个 Sentinel 进行连接, 各个 Sentinel 之间可以互相检查对方的可用性,
并进行信息交换。 你无须为运行的每个 Sentinel 分别设置其他 Sentinel 的地址, 因为 Sentinel
可以通过发布与订阅功能来自动发现正在监视相同主服务器的其他 Sentinel , 这一功能是通过向频道 sentinel:hello
发送信息来实现的。 与此类似, 你也不必手动列出主服务器属下的所有从服务器, 因为 Sentinel
可以通过询问主服务器来获得所有从服务器的信息。

  • 每个 Sentinel 会以每两秒一次的频率, 通过发布与订阅功能, 向被它监视的所有主服务器和从服务器的 sentinel:hello 频道发送一条信息, 信息中包含了 Sentinel 的 IP 地址、端口号和运行 ID (runid)。
  • 每个 Sentinel 都订阅了被它监视的所有主服务器和从服务器的 sentinel:hello 频道, 查找之前未出现过的 sentinel (looking for unknown sentinels)。 当一个 Sentinel 发现一个新的
    Sentinel 时, 它会将新的 Sentinel 添加到一个列表中, 这个列表保存了 Sentinel 已知的,
    监视同一个主服务器的所有其他 Sentinel 。
  • Sentinel 发送的信息中还包括完整的主服务器当前配置(configuration)。 如果一个 Sentinel 包含的主服务器配置比另一个 Sentinel 发送的配置要旧, 那么这个 Sentinel 会立即升级到新配置上。
  • 在将一个新 Sentinel 添加到监视主服务器的列表上面之前, Sentinel 会先检查列表中是否已经包含了和要添加的 Sentinel 拥有相同运行 ID 或者相同地址(包括 IP 地址和端口号)的 Sentinel , 如果是的话, Sentinel
    会先移除列表中已有的那些拥有相同运行 ID 或者相同地址的 Sentinel , 然后再添加新 Sentinel 。

参考链接:
关于docker 构建redis 主从/哨兵/集群网络问题
Redis 的 Sentinel 文档

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值