redis sentinel 简介

Redis Sentinel 是 Redis 官方提供的高可用(HA)解决方案,用于 监控主从架构中的故障并自动完成故障转移。当主节点(Master)宕机时,Sentinel 能自动选举新的主节点,通知从节点(Slave)和客户端更新配置,实现服务无缝切换。其核心功能包括:

  • 监控:持续检查 Redis 主从节点的健康状态。
  • 自动故障转移:主节点故障时,自动将从节点提升为主节点。
  • 配置提供:为客户端动态推送最新的主节点地址。
  • 通知:通过 API 通知管理员节点故障信息。

本次使用 1 主 + 2 从 + 3 Sentinel 的架构进行部署。

准备环境

  • 获取 Redis Docker 镜像。
Bash
docker pull redis:7.4.4
docker images
  • 创建目录 /home/docker/redis-sentinel,将后续相关的配置文件都集中存放在该目录。
Bash
mkdir -p /home/docker/redis-sentinel
  • 依次创建 master、salve、sentinel 的目录文件夹。
Bash
mkdir -p /home/docker/redis-sentinel/master-data
mkdir -p /home/docker/redis-sentinel/salve1-data
mkdir -p /home/docker/redis-sentinel/salve2-data
mkdir -p /home/docker/redis-sentinel/sentinel1-data
mkdir -p /home/docker/redis-sentinel/sentinel2-data
mkdir -p /home/docker/redis-sentinel/sentinel3-data
  • 创建用于 Redis 通信的专属 bridge。
Bash
docker network create --driver bridge --subnet 172.16.0.0/24 --gateway 172.16.0.1 redis-bridge
  • 查看是否创建成功。
Bash
docker network ls

关于 docker 网络

参考文档:https://outmanzzq.github.io/2019/10/22/docker-network/

Docker 默认有三个网络,可以通过 docker network ls 查看:

Bash
NETWORK ID     NAME     DRIVER    SCOPE
9ac8281b182c   bridge   bridge    local
99abdb470354   host     host      local
8e983d1c7d86   none     null      local

Docker 内置这三个网络,运行容器时,你可以使用 --network 标志来指定容器应连接到哪些网络;如果不指定,则 Docker 默认使用 --network=bridge。

Bash
docker run --network=host
  • host:与宿主机在同一个网络,没有独立 IP。
  • none:该模式将容器放置在它自己的网络栈中,但是并不进行任何配置,相当于关闭了容器的网络功能。
  • bridge:容器连接到 docker0 虚拟网卡,通过 docker0 网桥以及 Iptables nat 表配置与宿主机通信。

通过 ifconfig 可以查看到 docker0。

通过 ifconfig 查看 docker0。

在 bridge 模式下,连在同一网桥上的容器可以相互通信,本文的 Docker 配置将基于 bridge 模式。

单个容器分开部署

启动 master

  • 创建主节点启动配置文件:vim /home/docker/redis-sentinel/redis-master.conf
Config
# redis-master.conf

# 是否为守护进程
daemonize no
# 指定 redis 启动端口
port 6379
bind 0.0.0.0

# 设置连接密码
requirepass 123456
# 从节点连接主节点时使用的密码
masterauth 123456

# 使用 aop 持久化
appendonly yes
  • 启动 Redis 镜像。
Bash
docker run -it -d --name redis-master \
  --net=redis-bridge \
  --ip 172.16.0.10 \
  -p 6379:6379 \
  -v /home/docker/redis-sentinel/redis-master.conf:/etc/redis/redis.conf \
  -v /home/docker/redis-sentinel/master-data:/data \
  redis:7.4.4 \
  redis-server /etc/redis/redis.conf
  • 查看是否成功启动。
Bash
docker ps
  • 进入容器。
Bash
docker exec -it redis-master redis-cli -a 123456

启动 salve

  • 创建从节点启动配置文件:vim /home/docker/redis-sentinel/redis-salve1.conf
Config
# redis-salve1.conf

# 是否为守护进程
daemonize no
# 指定 redis 启动端口
port 6379
bind 0.0.0.0

# 设置连接密码
requirepass 123456
# 从节点连接主节点时使用的密码
masterauth 123456

# 使用 aop 持久化
appendonly yes

# 指定主节点的 IP 和端口,使用容器名称即可
replicaof redis-master 6379
  • 启动从节点镜像。
Bash
docker run -it -d --name redis-salve1 \
  --network redis-bridge \
  --ip 172.16.0.11 \
  -p 6479:6379 \
  -v /home/docker/redis-sentinel/redis-salve1.conf:/etc/redis/redis.conf \
  -v /home/docker/redis-sentinel/salve1-data:/data \
  redis:7.4.4 \
  redis-server /etc/redis/redis.conf
  • 查看是否启动成功。
Bash
docker ps
  • 进入从容器,尝试 set 会被拒绝。
Bash
docker exec -it redis-salve1 redis-cli -a 123456
进入 salve1 后尝试写入会被拒绝。
  • 验证主从是否成功。
Bash
docker exec redis-master redis-cli -a 123456 INFO replication
通过 INFO replication 查看主从复制状态。

启动第二个从节点

  • 创建从节点启动配置文件:vim /home/docker/redis-sentinel/redis-salve2.conf
Config
# redis-salve2.conf

# 是否为守护进程
daemonize no
# 指定 redis 启动端口
port 6379
bind 0.0.0.0

# 设置连接密码
requirepass 123456
# 从节点连接主节点时使用的密码
masterauth 123456

# 使用 aop 持久化
appendonly yes

# 指定主节点的 IP 和端口,使用容器名称即可
replicaof 172.16.0.10 6379
  • 启动从节点镜像。
Bash
docker run -it -d --name redis-salve2 \
  --network redis-bridge \
  --ip 172.16.0.12 \
  -p 6579:6379 \
  -v /home/docker/redis-sentinel/redis-salve2.conf:/etc/redis/redis.conf \
  -v /home/docker/redis-sentinel/salve2-data:/data \
  redis:7.4.4 \
  redis-server /etc/redis/redis.conf

启动 sentinel

  • 创建 sentinel 配置文件:vim /home/docker/redis-sentinel/redis-sentinel.conf
Config
# redis-sentinel.conf

# 端口号
port 26379

daemonize no

# 启用主机名解析
sentinel resolve-hostnames yes
# 监控主节点,2 个 Sentinel 同意即触发故障转移
sentinel monitor mymaster redis-master 6379 2
# 主节点密码
sentinel auth-pass mymaster 123456
# 5 秒无响应视为下线
sentinel down-after-milliseconds mymaster 5000
  • 启动 sentinel1。
Bash
docker run -it -d --name redis-sentinel1 \
  --network redis-bridge \
  --ip 172.16.0.20 \
  -p 26379:26379 \
  -v /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf \
  -v /home/docker/redis-sentinel/sentinel1-data:/data \
  redis:7.4.4 \
  redis-sentinel /etc/redis/sentinel.conf
  • 启动另外两个 sentinel,只需要修改映射端口和容器名称。
Bash
docker run -it -d --name redis-sentinel2 \
  --network redis-bridge \
  --ip 172.16.0.21 \
  -p 26479:26379 \
  -v /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf \
  -v /home/docker/redis-sentinel/sentinel2-data:/data \
  redis:7.4.4 \
  redis-sentinel /etc/redis/sentinel.conf

docker run -it -d --name redis-sentinel3 \
  --network redis-bridge \
  --ip 172.16.0.22 \
  -p 26579:26379 \
  -v /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf \
  -v /home/docker/redis-sentinel/sentinel3-data:/data \
  redis:7.4.4 \
  redis-sentinel /etc/redis/sentinel.conf

验证

检测主从状态:

Bash
docker exec -it redis-master redis-cli -a 123456 INFO replication

查看 Sentinel 监控:

Bash
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL masters

docker compose 部署

按照上述步骤,可以完整部署 Docker Sentinel 集群,但是需要一个个启动和配置容器,比较麻烦,因此可以通过 docker compose 来简化操作。配置文件使用前边单个容器部署中的配置。

新建 docker compose 配置文件:vim /home/docker/redis-sentinel/docker-compose.yml

YAML
networks:
  redis-bridge:
    external: true
    name: redis-bridge

services:
  redis-master:
    image: redis:7.4.4
    container_name: redis-master
    command: redis-server /etc/redis/redis.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.10
    volumes:
      - /home/docker/redis-sentinel/redis-master.conf:/etc/redis/redis.conf
      - /home/docker/redis-sentinel/master-data:/data
    ports:
      - "6379:6379"

  redis-slave1:
    image: redis:7.4.4
    container_name: redis-slave1
    command: redis-server /etc/redis/redis.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.11
    depends_on:
      - redis-master
    volumes:
      - /home/docker/redis-sentinel/redis-salve1.conf:/etc/redis/redis.conf
      - /home/docker/redis-sentinel/salve1-data:/data
    ports:
      - "6479:6379"

  redis-slave2:
    image: redis:7.4.4
    container_name: redis-slave2
    command: redis-server /etc/redis/redis.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.12
    depends_on:
      - redis-master
    volumes:
      - /home/docker/redis-sentinel/redis-salve2.conf:/etc/redis/redis.conf
      - /home/docker/redis-sentinel/salve2-data:/data
    ports:
      - "6579:6379"

  redis-sentinel1:
    image: redis:7.4.4
    container_name: redis-sentinel1
    command: redis-sentinel /etc/redis/sentinel.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.20
    volumes:
      - /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf
      - /home/docker/redis-sentinel/sentinel1-data:/data
    ports:
      - "26379:26379"

  redis-sentinel2:
    image: redis:7.4.4
    container_name: redis-sentinel2
    command: redis-sentinel /etc/redis/sentinel.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.21
    volumes:
      - /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf
      - /home/docker/redis-sentinel/sentinel2-data:/data
    ports:
      - "26479:26379"

  redis-sentinel3:
    image: redis:7.4.4
    container_name: redis-sentinel3
    command: redis-sentinel /etc/redis/sentinel.conf
    networks:
      redis-bridge:
        ipv4_address: 172.16.0.22
    volumes:
      - /home/docker/redis-sentinel/redis-sentinel.conf:/etc/redis/sentinel.conf
      - /home/docker/redis-sentinel/sentinel3-data:/data
    ports:
      - "26579:26379"

启动集群:

Bash
docker compose up -d

查看容器启动情况:

Bash
docker ps

进入 master 验证:

Bash
docker exec -it redis-master redis-cli -a 123456

主从复制验证:

Bash
docker exec -it redis-master redis-cli -a 123456 INFO replication

查看 sentinel 状态:

Bash
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL masters

批量停止、启动、重启容器:

Bash
docker compose stop|start|restart
# 也可以停止指定容器
docker compose stop|start|restart redis-salve2

清理并重启服务:

Bash
docker compose stop
docker compose rm -f
docker compose up -d

测试故障转移

  1. 查看原始主节点信息。
Bash
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
通过 Sentinel 查询当前主节点。
  1. 停止主节点。
Bash
docker stop redis-master
  1. 通过容器查看是否成功停止。
Bash
docker ps
停止 redis-master 后查看容器列表。
  1. 等待 10 秒后,再通过 Sentinel 查看是否切换为新的主节点。
Bash
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
等待一段时间后,Sentinel 已完成新的主节点切换。
  1. 登录到该从节点确认是否可以执行写入操作。
Bash
docker exec -it redis-salve2 redis-cli -a 123456
登录新的主节点后确认可以执行写入操作。
  1. 最后,再重新启动 redis-master 节点,确认是否加入集群。
Bash
docker restart redis-master
重新启动 redis-master 后确认节点重新加入集群。

感谢读到这里

日志还会继续,欢迎常来。

返回首页