docker-compose快速搭建redis哨兵模式高可用集群

3,407 阅读9分钟

     本次安装采用 Ubuntu Server X64 18.04 LTS 版本安装 redis 集群环境,集群节点为 1 主2从
PS:由于资源不够所以利用docker-compose的桥接网络部署在同一台机器,平时生产应该避免出现这一种把鸡蛋放在一个篮子的情况后续可能会基于Sentinel搭建redis高可用集群,docker自行安装

环境配置

主机名 IP 角色 系统 CPU/内存 磁盘
redsis-master 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G
redsis-slave-1 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G
redsis-slave-2 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G
redis-sentinel-1 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G
redis-sentinel-2 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G
redis-sentinel-3 192.168.23.134 Ubuntu Server 18.04 2 核 4G 40G

redis

# docker-compose.yml
version: '3'
services:
  master:
    image: redis
    container_name: redis-master
    command: redis-server --requirepass redis_pwd  --masterauth redis_pwd
    ports:
      - 6380:6379
  slave1:
    image: redis
    container_name: redis-slave-1
    ports:
      - 6381:6379
    command:  redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
  slave2:
    image: redis
    container_name: redis-slave-2
    ports:
      - 6382:6379
    command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd

docker-compose up 运行,加参数 -d 可以实现后台运行,我这里特意打印出日志

# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
d48696ad6446        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6382->6379/tcp   redis-slave-2
49e9f9057550        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6381->6379/tcp   redis-slave-1
18cf4f04ebbc        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6380->6379/tcp   redis-master

分别启了三个redis容器,对外暴露端口号为6382,6381,6380(与编排文件中的ports设置有关)

Redis Sentinel

    Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

    Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossipprotocols) 来接收关于主服务器是否下线的信息, 并使用投票协议(agreementprotocols) 来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。 虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器, 你可以在启动一个普通 Redis 服务器时通过给定 –sentinel 选项来启动 Redis Sentinel 。

# docker-compose.yml 
version: '3'
services:
  sentinel1:
    image: redis
    container_name: redis-sentinel-1
    ports:
      - 26379:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
  sentinel2:
    image: redis
    container_name: redis-sentinel-2
    ports:
    - 26380:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
  sentinel3:
    image: redis
    container_name: redis-sentinel-3
    ports:
      - 26381:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
  default:
    external:
      name: redis_default

挂载数据卷

# sentinel1.conf
port 26379
dir /tmp# 172.18.0.2是redis的主节点ip 
# 指示 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 172.18.0.2 (docker inspect [containerIP]可以获取) 端口号为 6379
# 将这个主服务器判断为失效至少需要 2 个 Sentinel 同意 (只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)
sentinel monitor mymaster 172.18.0.2 6379 2 
# 
sentinel auth-pass mymaster redis_pwd
# 指定了 Sentinel 认为服务器已经断线所需的毫秒数。
sentinel down-after-milliseconds mymaster 30000
# 指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 
# 这个数字越小, 完成故障转移所需的时间就越长。
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

因为三个机器,复制三份,这里的名字要和编排文件的volumes对应,docker-compose up -d运行

# -> 输出如下
NTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                NAMES
bbd6093a6bdf        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp, 0.0.0.0:26380->26379/tcp   redis-sentinel-2
69eb1530998d        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp, 0.0.0.0:26379->26379/tcp   redis-sentinel-1
019a72cdbc95        redis               "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp, 0.0.0.0:26381->26379/tcp   redis-sentinel-3
d48696ad6446        redis               "docker-entrypoint.s…"   18 minutes ago       Up 18 minutes       0.0.0.0:6382->6379/tcp               redis-slave-2
49e9f9057550        redis               "docker-entrypoint.s…"   18 minutes ago       Up 18 minutes       0.0.0.0:6381->6379/tcp               redis-slave-1
18cf4f04ebbc        redis               "docker-entrypoint.s…"   18 minutes ago       Up 18 minutes       0.0.0.0:6380->6379/tcp               redis-master

验证

redis

docker exec -it 18cf4f04ebbc redis-cli进入主机器

# -> info之前先进行授权 auth redis_pwd(requirepass的值)
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
# 从节点信息
slave0:ip=172.18.0.4,port=6379,state=online,offset=2492,lag=0
slave1:ip=172.18.0.3,port=6379,state=online,offset=2492,lag=1
master_replid:2760a09897b3d82d0e304265fcc2b030e1740300
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2492
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2492

exit退出去

Redis Sentinel

docker exec -it 69eb1530998d bash

 1) "name"
 2) "mymaster"
 3) "ip"
 4) "172.18.0.2"
 5) "port"
 6) "6379"
 7) "runid"
 8) "3fc8105ab0b5722b5deb266b9fdaddfa15a7e683"
 9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "747"
19) "last-ping-reply"
20) "747"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "8849"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "69121"
29) "config-epoch"
30) "0"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"
127.0.0.1:26379> 


记录

Redis启用密码认证

     Redis主从和clsuter支持密码认证的。redis启用密码认证一定要requirepass和masterauth同时设置。如果主节点设置了requirepass登录验证,在主从切换,slave在和master做数据同步的时候首先需要发送一个ping的消息给主节点判断主节点是否存活,再监听主节点的端口是否联通,发送数据同步等都会用到master的登录密码,否则无法登录,log会出现响应的报错。也就是说slave的masterauth和master的requirepass是对应的,所以建议redis启用密码时将各个节点的masterauth和requirepass设置为相同的密码,降低运维成本。当然设置为不同也是可以的,注意slave节点masterauth和master节点requirepass的对应关系就行。

  • masterauth作用:主要是针对master对应的slave节点设置的,在slave节点数据同步的时候用到。

  • requirepass作用:对登录权限做限制,redis每个节点的requirepass可以是独立、不同的。

主观下线和客观下线

     由上述配置知down-after-milliseconds 选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。 如果服务器在给定的毫秒数之内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线(subjectively down,简称 SDOWN)

  • 主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
  • 客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线。)客观下线条件只适用于主服务器

如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复[+PONG 、 -LOADING 或者 -MASTERDOWN 。], 那么 Sentinel 就会将这个服务器标记为主观下线。

Sentinel 命令

  • PING :返回 PONG 。
  • SENTINEL masters :列出所有被监视的主服务器,以及这些主服务器的当前状态。
  • SENTINEL slaves :列出给定主服务器的所有从服务器,以及这些从服务器的当前状态。 SENTINEL get-master-addr-by-name : 返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作, 或者针对这个主服务器的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号。
  • SENTINEL reset : 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清楚主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel 。
  • SENTINEL failover : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移 (不过发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置,其他 Sentinel 会根据这个配置进行相应的更新)。

结束

亲测成功!!!🍾🍾🍾

PS:外部访问需要配置redis.conf