docker-compose部署Redis-Sentinel集群

小柒博客 Docker评论6392字数 12367阅读41分13秒阅读模式

一、Redis-Sentinel简介

Sentinel(哨岗、哨兵)是Redis的高可用性(high availability)解决方案:由一个或多个Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

二、安装docker-compose

Linux上我们可以从Github上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases

1、运行以下命令以下载Docker Compose的v2.11.0版本

[root@localhost ~]# wget -O /usr/bin/docker-compose https://github.com/docker/compose/releases/download/v2.11.0/docker-compose-linux-x86_64

2、授权可执行权限

[root@localhost ~]# chmod +x /usr/bin/docker-compose

3、测试是否安装成功

[root@localhost ~]# docker-compose -v

Docker Compose version v2.11.0

三、部署Redis、Redis-Sentinel

1、创建Redis-Sentinel目录

[root@localhost ~]# mkdir -p /opt/redis-sentinel

2、创建docker-compose配置文件

[root@localhost ~]# cd /opt/redis-sentinel

[root@localhost redis-sentinel]# vim docker-compose.yml

version: '3.3'
services:
  redis-sentinel-1:
    image: redis:6.2.7
    container_name: redis-sentinel-1
    restart: always
    privileged: true
    ports:
      - '26379:26379'
    depends_on:
      - redis-master
      - redis-slave-1
      - redis-slave-2
    volumes:
      - /opt/redis-sentinel/conf:/etc/redis
      - /data/redis-sentinel/redis-sentinel-1:/data
    environment:
      TZ: "Asia/Shanghai"
    command: 
      redis-sentinel /etc/redis/redis-sentinel-1.conf
  redis-sentinel-2:
    image: redis:6.2.7
    container_name: redis-sentinel-2
    restart: always
    privileged: true
    ports:
      - '26380:26380'
    depends_on:
      - redis-master
      - redis-slave-1
      - redis-slave-2
    volumes:
      - /opt/redis-sentinel/conf:/etc/redis
      - /data/redis-sentinel/redis-sentinel-2:/data
    environment:
      TZ: "Asia/Shanghai"
    command: 
      redis-sentinel /etc/redis/redis-sentinel-2.conf
  redis-sentinel-3:
    image: redis:6.2.7
    container_name: redis-sentinel-3
    restart: always
    privileged: true
    ports:
      - '26381:26381'
    depends_on:
      - redis-master
      - redis-slave-1
      - redis-slave-2
    volumes:
      - /opt/redis-sentinel/conf:/etc/redis
      - /data/redis-sentinel/redis-sentinel-3:/data
    environment:
      TZ: "Asia/Shanghai"
    command: 
      redis-sentinel /etc/redis/redis-sentinel-3.conf

  redis-master:
    image: redis:6.2.7
    container_name: redis-master
    restart: always
    privileged: true
    build:
      network: host
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - /opt/redis-sentinel/conf/redis-master.conf:/etc/redis/redis-master.conf
      - /data/redis-sentinel/redis-master:/data
    command: 
      redis-server /etc/redis/redis-master.conf
  redis-slave-1:
    image: redis:6.2.7
    container_name: redis-slave-1
    restart: always
    privileged: true
    build:
      network: host
    depends_on:
      - redis-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - /opt/redis-sentinel/conf/redis-slave-1.conf:/etc/redis/redis-slave-1.conf
      - /data/redis-sentinel/redis-slave-1:/data
    command: 
      redis-server /etc/redis/redis-slave-1.conf
  redis-slave-2:
    image: redis:6.2.7
    container_name: redis-slave-2
    restart: always
    privileged: true
    build:
      network: host
    depends_on:
      - redis-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - /opt/redis-sentinel/conf/redis-slave-2.conf:/etc/redis/redis-slave-2.conf
      - /data/redis-sentinel/redis-slave-2:/data
    command: 
      redis-server /etc/redis/redis-slave-2.conf

3、创建Redis配置文件

# Master

[root@localhost redis-sentinel]# mkdir conf

[root@localhost redis-sentinel]# vim conf/redis-master.conf

# 绑定IP地址
bind 0.0.0.0
# 监听端口
port 6379
# 自定义密码
requirepass "123456"
# 超时时间
timeout 0
# 数据目录
dir "/data"
save 3600 1
save 300 100
save 60 10000
# PID文件
pidfile "/var/run/redis.pid"
# 日志文件
logfile "/tmp/redis.log"
appendfsync everysec
appendonly yes
dbfilename "dump.rdb"
# 设定连接主节点所使用的密码
masterauth "123456"

# Slave1

[root@localhost redis-sentinel]# vim conf/redis-slave-1.conf

# 绑定IP地址
bind 0.0.0.0
# 监听端口
port 6380
# 自定义密码
requirepass "123456"
# 超时时间
timeout 0
# 数据目录
dir "/data"
save 3600 1
save 300 100
save 60 10000
# PID文件
pidfile "/var/run/redis.pid"
# 日志文件
logfile "/tmp/redis.log"
appendfsync everysec
appendonly yes
dbfilename "dump.rdb"
# 设定连接主节点所使用的密码
masterauth "123456"
# 设置主Redis的地址和端口
replicaof redis-master 6379

# Slave2

[root@localhost redis-sentinel]# vim conf/redis-slave-2.conf

# 绑定IP地址
bind 0.0.0.0
# 监听端口
port 6381
# 自定义密码
requirepass "123456"
# 超时时间
timeout 0
# 数据目录
dir "/data"
save 3600 1
save 300 100
save 60 10000
# PID文件
pidfile "/var/run/redis.pid"
# 日志文件
logfile "/tmp/redis.log"
appendfsync everysec
appendonly yes
dbfilename "dump.rdb"
# 设定连接主节点所使用的密码
masterauth "123456"
# 设置主Redis的地址和端口
replicaof redis-master 6379

4、创建Redis-Sentinel配置文件

# sentinel-1

[root@localhost redis-sentinel]# vim conf/redis-sentinel-1.conf

# 哨兵的端口号
port 26379
# 设定密码认证
requirepass "123456"
# sentinel日志
logfile "/tmp/redis-sentinel.log"
# PID文件
pidfile "/var/run/redis-sentinel.pid"
# 数据目录
dir "/data"
# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor redis-sentinel redis-master 6379 2
# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass redis-sentinel 123456
# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds redis-sentinel 5000
# 指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长
sentinel parallel-syncs redis-sentinel 1
# 故障转移的超时时间,默认3分钟
sentinel failover-timeout redis-sentinel 5000
# 解析主机名(只有6.2以上版本的)
sentinel resolve-hostnames yes

# sentinel-2

[root@localhost redis-sentinel]# vim redis-sentinel-2.conf

# 哨兵的端口号
port 26380
# 设定密码认证
requirepass "123456"
# sentinel日志
logfile "/tmp/redis-sentinel.log"
# PID文件
pidfile "/var/run/redis-sentinel.pid"
# 数据目录
dir "/data"
# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor redis-sentinel redis-master 6379 2
# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass redis-sentinel 123456
# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds redis-sentinel 5000
# 指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长
sentinel parallel-syncs redis-sentinel 1
# 故障转移的超时时间,默认3分钟
sentinel failover-timeout redis-sentinel 5000
# 解析主机名(只有6.2以上版本的)
sentinel resolve-hostnames yes

# sentinel-3

[root@localhost redis-sentinel]# vim redis-sentinel-3.conf

# 哨兵的端口号
port 26381
# 设定密码认证
requirepass "123456"
# sentinel日志
logfile "/tmp/redis-sentinel.log"
# PID文件
pidfile "/var/run/redis-sentinel.pid"
# 数据目录
dir "/data"
# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor redis-sentinel redis-master 6379 2
# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass redis-sentinel 123456
# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds redis-sentinel 5000
# 指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长
sentinel parallel-syncs redis-sentinel 1
# 故障转移的超时时间,默认3分钟
sentinel failover-timeout redis-sentinel 5000
# 解析主机名(只有6.2以上版本的)
sentinel resolve-hostnames yes

5、创建数据目录

[root@localhost redis-sentinel]# mkdir -p /data/redis-sentinel/{redis-master,redis-slave-1,redis-slave-2}

[root@localhost redis-sentinel]# mkdir -p /data/redis-sentinel/redis-sentinel-{1..3}

6、启动容器

[root@localhost redis-sentinel]# docker-compose up -d

7、查看容器运行状态

[root@localhost redis-sentinel]# docker-compose ps

NAME                  COMMAND                     SERVICE             STATUS              PORTS

redis-master        "docker-entrypoint.s…"    redis-master        running             6379/tcp

redis-sentinel-1   "docker-entrypoint.s…"   redis-sentinel-1    running             6379/tcp, 0.0.0.0:26379->26379/tcp

redis-sentinel-2   "docker-entrypoint.s…"   redis-sentinel-2    running             6379/tcp, 0.0.0.0:26380->26380/tcp

redis-sentinel-3   "docker-entrypoint.s…"   redis-sentinel-3    running             6379/tcp, 0.0.0.0:26381->26381/tcp

redis-slave-1       "docker-entrypoint.s…"   redis-slave-1         running             6379/tcp

redis-slave-2       "docker-entrypoint.s…"   redis-slave-2         running             6379/tcp

8、访问Redis

[root@localhost redis-sentinel]# docker exec -it redis-master redis-cli

127.0.0.1:6379> auth 123456

OK

127.0.0.1:6379> info replication

# Replication

role:master

connected_slaves:2

slave0:ip=172.21.0.4,port=6380,state=online,offset=6551,lag=1

slave1:ip=172.21.0.3,port=6381,state=online,offset=6410,lag=1

master_failover_state:no-failover

master_replid:cf03aa830887e4d5d132944bc1728f0086859e71

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:6551

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:6551

9、主库写入测试数据,查询从库数据是否同步

127.0.0.1:6379> keys *

(empty array)

127.0.0.1:6379> set domain www.yangxingzhen.com

OK

127.0.0.1:6379> get domain

"www.yangxingzhen.com"

# 从库查询数据

[root@localhost redis-sentinel]# docker exec -it redis-slave-1 redis-cli -p 6380

127.0.0.1:6380> auth 123456

OK

127.0.0.1:6380> get domain

"www.yangxingzhen.com"

[root@localhost redis-sentinel]# docker exec -it redis-slave-2 redis-cli -p 6381

127.0.0.1:6381> auth 123456

OK

127.0.0.1:6381> get domain

"www.yangxingzhen.com"

10、模拟主库宕机,验证sentinel是否起作用

[root@localhost redis-sentinel]# docker-compose stop redis-master

11、查看sentinel日志

[root@localhost redis-sentinel]# docker exec -it redis-sentinel-1 tail -fn 100 /tmp/redis-sentinel.log

1:X 05 Dec 2022 14:33:48.451 # Sentinel ID is c84944aa698217d88ae1b98cfa0d76bcff36bd7e

1:X 05 Dec 2022 14:33:48.452 # +monitor master redis-sentinel 172.21.0.2 6379 quorum 2

1:X 05 Dec 2022 14:33:48.454 * +slave slave 172.21.0.4:6380 172.21.0.4 6380 @ redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:33:48.459 * +slave slave 172.21.0.3:6381 172.21.0.3 6381 @ redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:33:50.508 * +sentinel sentinel 528e1f3ec17699f22eadcef4b3547558e6425565 172.21.0.7 26381 @ redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:33:50.515 * +sentinel sentinel b828a2a8e11c71b5ce8b519eab7613286617b0d6 172.21.0.6 26380 @ redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:38:10.248 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:14.246 # +sdown master redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:38:14.392 # +new-epoch 1

1:X 05 Dec 2022 14:38:14.398 # +vote-for-leader 528e1f3ec17699f22eadcef4b3547558e6425565 1

1:X 05 Dec 2022 14:38:15.364 # +odown master redis-sentinel 172.21.0.2 6379 #quorum 3/2

1:X 05 Dec 2022 14:38:15.364 # Next failover delay: I will not start a failover before Mon Dec 5 14:38:25 2022

1:X 05 Dec 2022 14:38:15.513 # +config-update-from sentinel 528e1f3ec17699f22eadcef4b3547558e6425565 172.21.0.7 26381 @ redis-sentinel 172.21.0.2 6379

1:X 05 Dec 2022 14:38:15.513 # +switch-master redis-sentinel 172.21.0.2 6379 172.21.0.3 6381

1:X 05 Dec 2022 14:38:15.518 * +slave slave 172.21.0.4:6380 172.21.0.4 6380 @ redis-sentinel 172.21.0.3 6381

1:X 05 Dec 2022 14:38:15.525 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:15.525 * +slave slave :6379 6379 @ redis-sentinel 172.21.0.3 6381

1:X 05 Dec 2022 14:38:15.589 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:16.593 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:17.617 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:18.624 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:19.639 # Failed to resolve hostname 'redis-master'

1:X 05 Dec 2022 14:38:20.555 # +sdown slave :6379 6379 @ redis-sentinel 172.21.0.3 6381

sentinel在监测到主Redis宕机之后,通过选举,将一个从Redis选定为新的主Redis。通过查看sentinel日志可以发现,选定redis-slave-2(6381)为新的主Redis,同时将另外两个Redis作为从Redis。

注意:选定redis-slave-2为主Redis后,所有的配置文件都会被修改,主要是重新建立主从关系。

由于redis-master服务已经关掉,所以虽然sentinel将redis-master作为redis-slave-2的从服务,但是没有真正的建立。

此时需要重新启动redis-master服务,sentinel会重新建立一次主从关系

[root@localhost redis-sentinel]# docker-compose start redis-master

12、再次查询主从状态

[root@localhost redis-sentinel]# docker exec -it redis-slave-2 redis-cli -p 6381

127.0.0.1:6381> auth 123456

OK

127.0.0.1:6381> info replication

# Replication

role:master

connected_slaves:2

slave0:ip=172.21.0.4,port=6380,state=online,offset=212612,lag=0

slave1:ip=172.21.0.2,port=6379,state=online,offset=212330,lag=1

master_failover_state:no-failover

master_replid:1d3a4d26003edee57495015d494849316aafb99d

master_replid2:cf03aa830887e4d5d132944bc1728f0086859e71

master_repl_offset:212612

second_repl_offset:54161

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:212612

从结果可以看出,redis-master启动后会重新建立主从关系,sentinel配置文件也会同步更新。

13、Sentinel的工作原理总结

1)每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他Sentinel实例发送一个 PING 命令。

2)如果一个实例(instance)距离最后一次有效回复PING命令的时间超过 down-after-milliseconds选项所指定的值,则这个实例会被Sentinel标记为主观下线。

3)如果一个Master被标记为主观下线,则正在监视这个Master的所有Sentinel要以每秒一次的频率确认Master的确进入了主观下线状态。

4)当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线 。

5)在一般情况下,每个Sentinel会以每10秒一次的频率向它已知的所有Master,Slave发送INFO命令 。

6)当Master被Sentinel标记为客观下线时,Sentinel向下线的Master的所有Slave发送INFO命令的频率会从10秒一次改为每秒一次 。

7)若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。

若Master重新向Sentinel的PING命令返回有效回复,Master的主观下线状态就会被移除。

至此,docker-compose部署Redis-Sentinel集群完毕。

若文章图片、下载链接等信息出错,请在评论区留言反馈,博主将第一时间更新!如本文“对您有用”,欢迎随意打赏,谢谢!

继续阅读
历史上的今天
12月
5
Wechat
微信扫一扫,加我!
weinxin
微信公众号
微信扫一扫,关注我!
weinxin
Docker最后更新:2023-10-11
小柒博客
  • 本文由 小柒博客 发表于 2022年12月5日15:10:42
  • 声明:本站所有文章,如无特殊说明或标注,本站文章均为原创。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。转载请务必保留本文链接:https://www.yangxingzhen.com/8603.html
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

拖动滑块以完成验证