Docker搭建redis集群

Docker搭建redis集群

这里主要介绍redis的cluster集群,其他两种集群请看最后章节

环境介绍

Docker 版本:19.03.12

Docker 版本:docker-compose version 1.24.0, build 0aa59064

Redis 版本:6.0.8

系统版本:CentOS 7.8

简介

在这里插入图片描述

在 Redis 3.0 版本后正式推出 Redis 集群模式,该模式是 Redis 的分布式的解决方案,是一个提供在多个 Redis 节点间共享数据的程序集,且 Redis 集群是去中心化的,它的每个 Master 节点都可以进行读写数据,每个节点都拥有平等的关系,每个节点都保持各自的数据和整个集群的状态。

Redis 集群设计的主要目的是让 Redis 数据存储能够线性扩展,通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下其可以继续处理命令。但是,如果发生较大故障(例如,大多数主站不可用时)时集群会停止运行,即 redis 集群不能保证数据的强一致性。

优势

  • 高可用性: Redis 在集群模式下每个 Master 都是主从复制模式,其 Master 节点上的数据会实时同步到 Slave 节点上,当 Master 节点不可用时,其对应的 Slave 节点身份会更改为 Master 节点,保证集群的可用性
  • 数据横向扩展: Redis 是一个内存数据库,所有数据都存在内存中,在单节点中所在服务器能给与的内存是有一定限制。当数据量达到一定程度后,内存将不足以支撑这么多的数据存储,这时候需要将数据进行分片存储,而 Redis 集群模式就是将数据分片存储,非常方便横向扩展。

Redis 集群的数据分片

Redis 集群没有使用一致性 Hash, 而是引入了”哈希槽”的概念。Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

举个例子,比如当前集群有3个节点,那么:

在这里插入图片描述

  • 节点 A 包含 0 到 5460 号哈希槽;
  • 节点 B 包含 5461 到 10922 号哈希槽
  • 节点 C 包含 10923 到 16383 号哈希槽;

这种结构很容易”添加”或者”删除”节点. 比如如果我想新添加个节点 D,我需要从节点 A, B, C 中得部分槽转移到节点 D 上, 如果我想移除节点 A,则需要将 A 中的槽移到 B 和 C 节点上,然后将没有任何槽的 A 节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

Redis 支持多个 key 操作,只要这些 key 在一个单个命令中执行(或者一个事务,或者 Lua 脚本执行),那么它们就属于相同的 Hash 槽。你也可以用 hash tags 命令强制多个 key 都在相同的 hash 槽中。

Redis 集群的主从复制

在这里插入图片描述

在 Redis 集群模式下,为了防止集群部分节点因宕机等情况造成不可用,故而 Redis 集群使用了主从复制模式。在该模式下要求 Redis 集群至少要存在六个节点,其中三个节点为主节点,能够对外提供读写。还有三个节点为从节点,会同步其对应的主节点的数据。当某个主节点出现问题不可用时,Redis 将通过选举算法从主节点对应的从节点中选择一个节点(主节点存在多个从节点的情况下),将其更改为一个新的主节点,且能够对外提供服务。

例如,在存在 A,B,C 三个主节点和其对应的 (A1、A2),(B1、B2),(C1、C2) 六个从节点,共九个节点中,如果节点 A 节点挂掉,那么其对应的从节点 A1、A2 节点将通过选举算法,选择其中一个节点提升为主节点,以确保集群能够正常服务。不过当 A1、A2 两个从节点或者或者半数以上主节点不可用时,那么集群也是不可用的

在部署 Redis 集群模式时,至少需要六个节点组成集群才能保证集群的可用性。

部署

第一种集群部署方式:使用别人已经配置好的镜像,拿来即用

这里对待部署的 Redis 集群的节点进行分配,安排如下:由于资源有限,这里共用了一台服务器,设置了六个不同的端口。

服务器ip端口
192.168.1.1307001
192.168.1.1307002
192.168.1.1307003
192.168.1.1307004
192.168.1.1307005
192.168.1.1307006

创建docker-compose文件

version: '3.3'

services:
  redis1:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7001
  redis2:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7002
  redis3:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7003
  redis4:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7004
  redis5:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7005
  redis6:
    image: publicisworldwide/redis-cluster
    network_mode: host
    restart: always
    environment:
      - REDIS_PORT=7006

启动所有redis

docker-compose up -d

查看docker版本

文档中可查看docker版本支持的docker-compose.yml版本,为了方便大家查看,我复制出来了。不过一般来说,docker升级比较快,功能迭代也很快,最好还是用最新版本。

Compose file formatDocker Engine release
Compose specification19.03.0+
3.819.03.0+
3.718.06.0+
3.618.02.0+
3.517.12.0+
3.417.09.0+
3.317.06.0+
3.217.04.0+
3.11.13.1+
3.01.13.0+
2.417.12.0+
2.317.06.0+
2.21.13.0+
2.11.12.0+
2.01.10.0+
1.01.9.1.+

部署cluster

直接运行以下命令

docker run --rm -it inem0o/redis-trib create --replicas 1 192.168.1.130:7001 192.168.1.130:7002 192.168.1.130:7003 192.168.1.130:7004 192.168.1.130:7005 192.168.1.130:7006

会出现

Creating cluster
Performing hash slots allocation on 6 nodes…
Using 3 masters:
192.168.1.130:7001
192.168.1.130:7002
192.168.1.130:7003
Adding replica 192.168.1.130:7004 to 192.168.1.130:7001
Adding replica 192.168.1.130:7005 to 192.168.1.130:7002
Adding replica 192.168.1.130:7006 to 192.168.1.130:7003
M: 3592057f921dd65e487cd709d67487a11f7e2801 192.168.1.130:7001
slots:0-5460 (5461 slots) master
M: 60cb3e3301db04092ff1fd4301bb0292316c7d49 192.168.1.130:7002
slots:5461-10922 (5462 slots) master
M: 6a5b84956d324180d6eb8a57d959283714419a78 192.168.1.130:7003
slots:10923-16383 (5461 slots) master
S: f8a8c4f0f1413f7f98eb0b8aca219e9ffc4d62e2 192.168.1.130:7004
replicates 3592057f921dd65e487cd709d67487a11f7e2801
S: 27cedbf431c02009a9ea82fbf75eccf33b76cd7a 192.168.1.130:7005
replicates 60cb3e3301db04092ff1fd4301bb0292316c7d49
S: b2d3246317b692a22e7f016e61782fd719d87a8d 192.168.1.130:7006
replicates 6a5b84956d324180d6eb8a57d959283714419a78
Can I set the above configuration? (type ‘yes’ to accept):

输入yes

Nodes configuration updated
Assign a different config epoch to each node
Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join…
Performing Cluster Check (using node 192.168.1.130:7001)
M: 3592057f921dd65e487cd709d67487a11f7e2801 192.168.1.130:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: b2d3246317b692a22e7f016e61782fd719d87a8d 192.168.1.130:7006@17006
slots: (0 slots) slave
replicates 6a5b84956d324180d6eb8a57d959283714419a78
M: 60cb3e3301db04092ff1fd4301bb0292316c7d49 192.168.1.130:7002@17002
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: f8a8c4f0f1413f7f98eb0b8aca219e9ffc4d62e2 192.168.1.130:7004@17004
slots: (0 slots) slave
replicates 3592057f921dd65e487cd709d67487a11f7e2801
S: 27cedbf431c02009a9ea82fbf75eccf33b76cd7a 192.168.1.130:7005@17005
slots: (0 slots) slave
replicates 60cb3e3301db04092ff1fd4301bb0292316c7d49
M: 6a5b84956d324180d6eb8a57d959283714419a78 192.168.1.130:7003@17003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
Check for open slots…
Check slots coverage…
[OK] All 16384 slots covered.

第二种集群部署方式:自己修改配置文件

这里对待部署的 Redis 集群的节点进行分配,安排如下:由于资源有限,这里共用了一台服务器,设置了六个不同的端口。

服务器ip端口
192.168.1.1306391
192.168.1.1306392
192.168.1.1306393
192.168.1.1306394
192.168.1.1306395
192.168.1.1306396

准备配置文件

根目录下新建/redis-cluster/config文件夹,将配置文件上传到对应目录下,/redis-cluster/config目录下上传的配置文件都会挂载到redis容器里

配置文件目录结构:

redis-cluster/
├── config
│   ├── nodes-6391.conf		#redis配置文件
│   ├── nodes-6392.conf
│   ├── nodes-6393.conf
│   ├── nodes-6394.conf
│   ├── nodes-6395.conf
│   ├── nodes-6396.conf
│   └── redis.sh			#集群脚本
└── docker-compose.yml		 #docker-compose脚本

docker-compose.yml

version: "3"
services:
  redis-master1:
    image: redis:6.0.8 # 基础镜像
    container_name: redis-master1 # 容器名称
    working_dir: /config # 切换工作目录
    environment: # 环境变量
      - PORT=6391 # 会使用config/nodes-${PORT}.conf这个配置文件
    ports: # 映射端口,对外提供服务
      - 6391:6391 # redis的服务端口
      - 16391:16391 # redis集群监控端口
    stdin_open: true # 标准输入打开
    tty: true # 后台运行不退出
    network_mode: host # 使用host模式
    privileged: true # 拥有容器内命令执行的权限
    volumes:
      - /redis-cluster/config:/config #配置文件目录映射到宿主机
    entrypoint: # 设置服务默认的启动程序
      - /bin/bash
      - redis.sh
  redis-master2:
    image: redis:6.0.8
    working_dir: /config
    container_name: redis-master2
    environment:
      - PORT=6392
    ports:
      - 6392:6392
      - 16392:16392
    stdin_open: true
    network_mode: host
    tty: true
    privileged: true
    volumes:
      - /redis-cluster/config:/config
    entrypoint:
      - /bin/bash
      - redis.sh
  redis-master3:
    image: redis:6.0.8
    container_name: redis-master3
    working_dir: /config
    environment:
      - PORT=6393
    ports:
      - 6393:6393
      - 16393:16393
    stdin_open: true
    network_mode: host
    tty: true
    privileged: true
    volumes:
      - /redis-cluster/config:/config
    entrypoint:
      - /bin/bash
      - redis.sh
  redis-slave1:
    image: redis:6.0.8
    container_name: redis-slave1
    working_dir: /config
    environment:
      - PORT=6394
    ports:
      - 6394:6394
      - 16394:16394
    stdin_open: true
    network_mode: host
    tty: true
    privileged: true
    volumes:
      - /redis-cluster/config:/config
    entrypoint:
      - /bin/bash
      -  
  redis-slave2:
    image: redis:6.0.8
    working_dir: /config
    container_name: redis-slave2
    environment:
      - PORT=6395
    ports:
      - 6395:6395
      - 16395:16395
    stdin_open: true
    network_mode: host
    tty: true
    privileged: true
    volumes:
      - /redis-cluster/config:/config
    entrypoint:
      - /bin/bash
      - redis.sh
  redis-slave3:
    image: redis:6.0.8
    container_name: redis-slave3
    working_dir: /config
    environment:
      - PORT=6396
    ports:
      - 6396:6396
      - 16396:16396
    stdin_open: true
    network_mode: host
    tty: true
    privileged: true
    volumes:
      - /redis-cluster/config:/config
    entrypoint:
      - /bin/bash
      - redis.sh

nodes-{port}.conf

#127.0.0.1修改为0.0.0.0
bind 0.0.0.0

#关闭保护模式
protected-mode no

#数据库镜像备份的文件rdb/AOF文件放置的路径修改为/data
dir "/data"

# 开启集群功能
cluster-enabled yes

# 设置运行端口
port 6391

# 设置节点超时时间,单位毫秒
cluster-node-timeout 15000

# 集群内部配置文件,每个配置修改程相应的端口
cluster-config-file nodes-6391.conf

redis.sh

上传后redis.sh后,修改脚本权限

chmod +x /redis-cluster/config/redis.sh

redis.sh脚本的作用是根据环境变量中的PORT属性,以指定配置文件来启动Redis容器;

redis-server /config/nodes-${PORT}.conf
  • redis-cluster目录下,使用docker-compose命令来启动所有容器

    docker-compose up -d
    
  • 停止所有容器

    docker-compose up
    
  • 查看容器是否运行成功

    docker ps
    
  • 此时进入redis-master1容器之中,初始化Redis集群;

    # 进入Redis容器
    docker exec -it redis-master1 /bin/bash
    # 初始化Redis集群命令
    redis-cli --cluster create \
    192.168.1.130:6391 192.168.1.130:6392 192.168.1.130:6393 \
    192.168.1.130:6394 192.168.1.130:6395 192.168.1.130:6396 \
    --cluster-replicas 1
    
  • 集群创建过程中会让你确认配置,输入yes确认即可;
    在这里插入图片描述

  • Redis集群创建成功后会输出如下信息;

在这里插入图片描述

  • 创建成功后,在这个redis-master1容器里继续使用redis-cli命令就连接到其中一个Redis服务了;

    # 单机模式启动
    redis-cli -h 127.0.0.1 -p 6391
    # 集群模式启动
    redis-cli -c -h 127.0.0.1 -p 6391
    
  • 之后通过cluster nodes命令可以查看节点信息,发现符合原来3主3从的预期。

SpringBoot中使用Redis集群

  • 修改application.yml配置文件,添加Redis集群配置即可;
spring:
  redis:
#    host: 192.168.1.130 # Redis服务器地址
#    database: 0 # Redis数据库索引(默认为0)
#    port: 6379 # Redis服务器连接端口
    password: # Redis服务器连接密码(默认为空)
    timeout: 3000ms # 连接超时时间
    lettuce:
      pool:
        max-active: 8 # 连接池最大连接数
        max-idle: 8 # 连接池最大空闲连接数
        min-idle: 0 # 连接池最小空闲连接数
        max-wait: -1ms # 连接池最大阻塞等待时间,负值表示没有限制
    cluster:
      nodes:
        - 192.168.1.130:6391
        - 192.168.1.130:6392
        - 192.168.1.130:6393
        - 192.168.1.130:6394
        - 192.168.1.130:6395
        - 192.168.1.130:6396

常见问题

Redis 集群中的一致性

Redis 在官方文档中提及,其并不能保证数据的强一致性,即 Redis 集群在特定的条件下写入的数据可能会丢失,主要原因是因为 Redis 集群使用了异步复制模式,其写入的操作过程如下:

在这里插入图片描述

执行顺序如下:

  • ① 客户端向任意一台主节点写入一条命令;
  • ② 主节点对向客户端回复命令执行的状态;
  • ③ 主节点将写操作命令传递给他的从节点;

Redis 集群对性能和一致性之间做出权衡,设置主节点在接收到客户端写命令后再将执行的命令发送到各个从节点进行同步,这个过程是异步操作,且主节点不会等待从节点回复信息就立即回复客户端命令的执行状态。这样减少同步操作,可以很大提高系统的执行速度,避免等待从节点回复消息这个过程成为系统性能的瓶颈。

然而,因为主节点不等待从节点收到信息后进行回复,就将命令的执行状态回复给了客户端,那么在节点出现问题时很可能导致出现数据丢失问题,比如客户端向主节点发送一条命令,然后主节点将该命令异步发送到它的从节点进行数据备份,然后立即回复客户端命令的执行状态。如果在这个过程中,主节点出现问导致宕机,且从节点在处理主节点发送过来的同步数据时,也发生错误。这时正好赶上主节点宕机等不可用情况,那么从节点将转换为新的主节点,在之前主节点执行的命令将丢失。

Redis 集群失败状态

在 Redis 集群模式下也不可能百分百保证集群可用性,当发生不可预知的事件导致 Redis 集群将进入失败状态,在这种状态下 Redis 集群将不能正常提供服务。其中进入失败状态的条件主要为:

  • ① 全部节点都宕机,集群将进入 fail 状态;
  • ② 半数以上主节点不可用,集群将进入 fail 状态;
  • ③ 任意主节点挂掉,且该主节点没有对应的从节点或者从节点也全部挂掉,集群将进入 fail 状态;

Redis 集群的不足

  • 不支持多数据库,只能使用 0 数据库,执行 select 0 命令;
  • 键事务支持有限,当多个键分布在不同节点时无法使用事务,同一节点才能支持事务;
  • 键的批量操作支持有限,比如 mset, mget 命令,如果多个键映射在不同的槽中,就不能正常使用这些命令了;
  • 键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点;
  • 复制结构只支持单层结构,不支持树型结构。

其他两种集群

主从

缺点

redis通过主从复制来实现高可用,但是发生故障时需要人工进行主从切换,效率低下

部署

​ 服务器ip:192.168.1.130

​ 主节点:192.168.1.130:6379

​ 从节点:192.168.1.131:6380,192.168.1.131:6381

  • 运行三个redis容器

    docker run --name redis-6379 -p 6379:6379 -d redis:6.0.8
    docker run --name redis-6380 -p 6380:6379 -d redis:6.0.8
    docker run --name redis-6381 -p 6381:6379 -d redis:6.0.8
    
  • redis-6380容器配置主从

    #进入从节点的redis-6380容器
    [root@192.168.1.131 redis-cluster]# docker exec -it redis-6380 redis-cli
    #使之作为从节点
    127.0.0.1:6379> slaveof 192.168.1.130 6379
    OK
    #role查看角色是否为slave
    127.0.0.1:6379> role
    1) "slave"
    2) "192.168.1.130"
    3) (integer) 6379
    4) "connected"
    5) (integer) 0
    127.0.0.1:6379> exit
    
  • redis-6381容器配置主从,同上

  • 测试

    #进入主节点,将name的为test
    [root@192.168.1.130 redis-cluster]# docker exec -it redis-6379 redis-cli
    127.0.0.1:6379> set name test
    OK
    127.0.0.1:6379> exit
    #进入redis-6380从节点查看name是否同步过来
    [root@192.168.1.131 redis-cluster]# docker exec -it redis-6380 redis-cli
    127.0.0.1:6379> get name
    "test"
    127.0.0.1:6379> exit
    #进入redis-6381从节点查看name是否同步过来
    [root@192.168.1.131 redis-cluster]# docker exec -it redis-6381 redis-cli
    127.0.0.1:6379> get name
    "test"
    127.0.0.1:6379> exit
    
  • 取消redis-6381从节点

    [root@192.168.1.131 redis-cluster]# docker exec -it redis-6381 redis-cli slaveof NO ONE
    OK
    [root@192.168.1.131 redis-cluster]#
    

哨兵

哨兵模式实现了redis主从的自动切换,提高了redis集群的可用性,提高了redis集群的故障转移效率

架构图

在这里插入图片描述

目录结构
/redis-sentinel
├── sentinel
│   ├── docker-compose.yml
│   ├── redis-sentinel-1.conf
│   ├── redis-sentinel-2.conf
│   └── redis-sentinel-3.conf
└── server
    ├── data
    │   ├── redis-master
    │   │   └── dump.rdb
    │   ├── redis-slave-1
    │   │   └── dump.rdb
    │   └── redis-slave-2
    │       └── dump.rdb
    ├── docker-compose.yml
    ├── redis-master.conf
    ├── redis-slave1.conf
    └── redis-slave2.conf
Sentinel配置
sentinel的docker-compose.yml文件
---

version: '3'

services:
  redis-sentinel-1:
    image: redis
    container_name: redis-sentinel-1
    restart: always
    # 为了规避Docker中端口映射可能带来的问题
    # 这里选择使用host网络
    network_mode: host
    volumes:
      - ./redis-sentinel-1.conf:/usr/local/etc/redis/redis-sentinel.conf
    # 指定时区,保证容器内时间正确
    environment:
      TZ: "Asia/Shanghai"
    sysctls:
      net.core.somaxconn: '511'
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
  redis-sentinel-2:
    image: redis
    container_name: redis-sentinel-2
    restart: always
    network_mode: host
    volumes:
      - ./redis-sentinel-2.conf:/usr/local/etc/redis/redis-sentinel.conf
    environment:
      TZ: "Asia/Shanghai"
    sysctls:
      net.core.somaxconn: '511'
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
  redis-sentinel-3:
    image: redis
    container_name: redis-sentinel-3
    restart: always
    network_mode: host
    volumes:
      - ./redis-sentinel-3.conf:/usr/local/etc/redis/redis-sentinel.conf
    environment:
      TZ: "Asia/Shanghai"
    sysctls:
      net.core.somaxconn: '511'
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
redis-sentinel-1.conf
# bind 127.0.0.1

# 哨兵的端口号
# 因为各个哨兵节点会运行在单独的Docker容器中
# 所以无需担心端口重复使用
# 如果需要在单机
port 26379

# 设定密码认证
requirepass 123456

# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor local-master 127.0.0.1 6379 2

# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456

# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
redis-sentinel-2.conf
# bind 127.0.0.1

# 哨兵的端口号
# 因为各个哨兵节点会运行在单独的Docker容器中
# 所以无需担心端口重复使用
# 如果需要在单机
port 26380

# 设定密码认证
requirepass 123456

# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor local-master 127.0.0.1 6379 2

# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456

# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
redis-sentinel-3.conf
# bind 127.0.0.1

# 哨兵的端口号
# 因为各个哨兵节点会运行在单独的Docker容器中
# 所以无需担心端口重复使用
# 如果需要在单机
port 26381

# 设定密码认证
requirepass 123456

# 配置哨兵的监控参数
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是为这个被监控的master起的名字
# ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名
# redis-port是被监控节点所监听的端口号
# quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了
sentinel monitor local-master 127.0.0.1 6379 2

# 连接主节点的密码
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456

# master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
Redis配置
redis的docker-compose文件
---

version: '3'

services:
  # 主节点的容器
  redis-server-master:
    image: redis
    container_name: redis-server-master
    restart: always
    # 为了规避Docker中端口映射可能带来的问题
    # 这里选择使用host网络
    network_mode: host
    # 指定时区,保证容器内时间正确
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      # 映射配置文件和数据目录
      - ./redis-master.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-master:/data
    sysctls:
      # 必要的内核参数
      net.core.somaxconn: '511'
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # 从节点1的容器
  redis-server-slave-1:
    image: redis
    container_name: redis-server-slave-1
    restart: always
    network_mode: host
    depends_on:
      - redis-server-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - ./redis-slave1.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-slave-1:/data
    sysctls:
      net.core.somaxconn: '511'
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # 从节点2的容器
  redis-server-slave-2:
    image: redis
    container_name: redis-server-slave-2
    restart: always
    network_mode: host
    depends_on:
      - redis-server-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - ./redis-slave2.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-slave-2:/data
    sysctls:
      net.core.somaxconn: '511'
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-master.conf
# bind 127.0.0.1

# 启用保护模式
# 即在没有使用bind指令绑定具体地址时
# 或在没有设定密码时
# Redis将拒绝来自外部的连接
# protected-mode yes

# 监听端口
port 6379

# 启动时不打印logo
# 这个不重要,想看logo就打开它
always-show-logo no

# 设定密码认证
requirepass 123456

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的键,会影响数据安全
# 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间
# 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃
rename-command KEYS ""

# 此外还应禁止 FLUSHALL 和 FLUSHDB 命令
# 这两个命令会清空数据,并且不会失败
redis-slave1.conf
# bind 127.0.0.1

# 启用保护模式
# 即在没有使用bind指令绑定具体地址时
# 或在没有设定密码时
# Redis将拒绝来自外部的连接
# protected-mode yes

# 监听端口
port 6380

# 启动时不打印logo
# 这个不重要,想看logo就打开它
always-show-logo no

# 设定密码认证
requirepass 123456

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的键,会影响数据安全
# 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间
# 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃
rename-command KEYS ""

# 此外还应禁止 FLUSHALL 和 FLUSHDB 命令
# 这两个命令会清空数据,并且不会失败

# 配置master节点信息
# 格式:
#slaveof <masterip> <masterport>
# 此处masterip所指定的redis-server-master是运行master节点的容器名
# Docker容器间可以使用容器名代替实际的IP地址来通信
slaveof 127.0.0.1 6379

# 设定连接主节点所使用的密码
masterauth "123456"
redis-slave2.conf
# bind 127.0.0.1

# 启用保护模式
# 即在没有使用bind指令绑定具体地址时
# 或在没有设定密码时
# Redis将拒绝来自外部的连接
# protected-mode yes

# 监听端口
port 6381

# 启动时不打印logo
# 这个不重要,想看logo就打开它
always-show-logo no

# 设定密码认证
requirepass 123456

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的键,会影响数据安全
# 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间
# 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃
rename-command KEYS ""

# 此外还应禁止 FLUSHALL 和 FLUSHDB 命令
# 这两个命令会清空数据,并且不会失败

# 配置master节点信息
# 格式:
#slaveof <masterip> <masterport>
# 此处masterip所指定的redis-server-master是运行master节点的容器名
# Docker容器间可以使用容器名代替实际的IP地址来通信
slaveof 127.0.0.1 6379

# 设定连接主节点所使用的密码
masterauth "123456"
哨兵模式验证
启动redis

/redis-sentinel/server下执行

docker-compose up
启动sentinel

/redis-sentinel/sentinel下执行

docker-compose up

全部正常启动后

[root@rabbit1 server]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS              PORTS     NAMES
d468f032604a   redis     "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes                  redis-server-slave-2
59d4f375cafc   redis     "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes                  redis-server-slave-1
7850df576f57   redis     "docker-entrypoint.s…"   8 minutes ago   Up About a minute             redis-server-master
d0b5fd7a3929   redis     "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes                  redis-sentinel-3
5f475fc9bf9a   redis     "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes                  redis-sentinel-1
4950fa03f567   redis     "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes                  redis-sentinel-2

进入主服务器查看

[root@rabbit1 server]# docker exec -it redis-server-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=192.168.1.130,port=6381,state=online,offset=21464,lag=1
slave1:ip=192.168.1.130,port=6380,state=online,offset=21464,lag=1
master_replid:98c6a6ad25de45d00520f4f1500e9522ce89a4c5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:21464
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:21464

然后停掉主节点,查看哨兵是否正常进行选举

[root@rabbit1 server]# docker stop redis-server-master
redis-server-master
[root@rabbit1 server]# docker logs -f redis-sentinel-1 
1:X 24 Feb 2021 15:18:30.895 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 24 Feb 2021 15:18:30.895 # Redis version=6.0.10, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 24 Feb 2021 15:18:30.895 # Configuration loaded
1:X 24 Feb 2021 15:18:30.899 * Running mode=sentinel, port=26379.
1:X 24 Feb 2021 15:18:30.914 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:18:30.914 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:18:30.914 # Sentinel ID is 04282ab7ae6ca74e2ee5ac3bde57c9e5299b2e6a
1:X 24 Feb 2021 15:18:30.914 # +monitor master local-master 192.168.1.130 6379 quorum 2
1:X 24 Feb 2021 15:18:40.366 * +sentinel sentinel 05b83e725b0b30f3bab775b6b5aac5002c180108 192.168.1.130 26380 @ local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:18:40.368 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:18:40.368 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:18:42.358 * +sentinel sentinel 1cf1c4136fe3c22b31cd3004ba8806346828a668 192.168.1.130 26381 @ local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:18:42.364 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:18:42.364 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:18:50.333 * +slave slave 192.168.1.130:6381 192.168.1.130 6381 @ local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:18:50.337 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:18:50.337 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:18:50.337 * +slave slave 192.168.1.130:6380 192.168.1.130 6380 @ local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:18:50.338 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:18:50.338 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:21:30.519 # +sdown master local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:21:30.543 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:21:30.543 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:21:30.543 # +new-epoch 1
1:X 24 Feb 2021 15:21:30.560 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:21:30.560 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:21:30.560 # +vote-for-leader 1cf1c4136fe3c22b31cd3004ba8806346828a668 1
1:X 24 Feb 2021 15:21:30.575 # +odown master local-master 192.168.1.130 6379 #quorum 3/2
1:X 24 Feb 2021 15:21:30.575 # Next failover delay: I will not start a failover before Wed Feb 24 15:27:31 2021
1:X 24 Feb 2021 15:21:31.753 # +config-update-from sentinel 1cf1c4136fe3c22b31cd3004ba8806346828a668 192.168.1.130 26381 @ local-master 192.168.1.130 6379
1:X 24 Feb 2021 15:21:31.753 # +switch-master local-master 192.168.1.130 6379 192.168.1.130 6380
1:X 24 Feb 2021 15:21:31.754 * +slave slave 192.168.1.130:6381 192.168.1.130 6381 @ local-master 192.168.1.130 6380
1:X 24 Feb 2021 15:21:31.754 * +slave slave 192.168.1.130:6379 192.168.1.130 6379 @ local-master 192.168.1.130 6380
1:X 24 Feb 2021 15:21:31.757 # Could not rename tmp config file (Device or resource busy)
1:X 24 Feb 2021 15:21:31.758 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 24 Feb 2021 15:22:01.795 # +sdown slave 192.168.1.130:6379 192.168.1.130 6379 @ local-master 192.168.1.130 6380

通过查看哨兵的日志,可看到哨兵停掉了6379这个主节点,将6380选举了新的主节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木一番

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值