Skip to content

高可用与集群

主从复制模式

主从复制简介

主从复制(Master-Slave Replication),是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave)。数据的复制是单向的,只能由主节点复制到从节点。

默认情况下,每台Redis服务器都是主节点。
一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

Redis主从复制通过 全量+增量同步异步命令传播 实现数据冗余,结合 复制ID、偏移量、复制积压缓冲区 等机制优化网络中断后的恢复效率。虽然保证了高可用性和读写分离,但需注意异步复制带来的数据延迟问题。 Redis主从模型分析图

  • 数据冗余
    主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  • 负载均衡
    在主从复制的基础上,配合读写分离,可以由主节点提供服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载。
    尤其可以在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  • 故障恢复
    当主节点出现问题时,可以由从节点提供服务(需手动配置),实现快速的故障恢复;实际上是一种服务的冗余。
  • 高可用基石
    主从复制是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

主从复制原理

  • 同步初始数据(全量同步)
    当一个从服务器启动并与主服务器建立连接后,它会请求主服务器发送所有数据的副本。如果这是从服务器首次连接到主服务器,主服务器将执行 BGSAVE 命令生成 RDB 文件并传输给从服务器。同时主服务器依然会接收客户端请求,使用复制积压缓冲区记录生成 RDB 期间的新写命令,待从节点同步完 RDB 文件数据后,主节点将复制积压缓冲区中的写命令发送给从节点,使从节点数据与主节点完全一致。 主从复制数据初始化
  • 命令传播
    初始同步完成后,主服务器会持续将接收到的写命令异步发送给从服务器(通过复制流),以确保从服务器的数据保持最新状态。主节点不会等待从节点确认,因此从节点数据可能短暂落后(最终一致性 CAP中的AP模型)。
  • 部分重同步
    为了优化网络带宽使用和减少同步时间,在某些情况下,Redis 支持部分重同步。这意味着如果主从之间的连接短暂断开,从服务器可以尝试只获取断开期间丢失的部分数据而不是全部重新同步。这依赖于复制积压缓冲区(replication backlog),这是一个固定大小的缓冲区,保存了最近一段时间内的写命令。 主从复制断点续传

主从复制部署

主节点不需要做任何改变
从节点都需要修改配置加上主节点信息并重启

shell
cd /opt/software/redis/redis-stable
vim redis.conf
shell
# replicaof <主节点IP> <端口>
replicaof 172.24.57.250 6379

# 如果主节点配置了密码,还需要配置 masterauth <主节点密码>
masterauth 1qaz@WSX

replicaof

配置完成并重启后,在主库检查从节点信息

shell
redis-cli
shell
auth 1qaz@WSX

info replication

replication

TIP

在主节点查看从节点信息时,注意查看 state 状态
state = online 时,表示正常,否则注意查看 网络,防火墙 等配置

配置完成并重启后,在从节点查看节点信息

shell
redis-cli
shell
auth 1qaz@WSX

info replication

replication

TIP

在从节点查看节点信息时,注意查看 master_link_status 状态
master_link_status = up 时,表示正常,否则注意查看 网络,防火墙 等配置

主从复制风暴

简介

主从复制风暴指的是在 Redis 主从架构中,由于某些原因导致从节点频繁尝试与主节点进行全量同步(full resynchronization),进而给主节点带来巨大压力,甚至可能导致整个集群的服务质量下降或不可用的情况。这种情况通常发生在网络不稳定、配置不当或者系统资源不足等情况下。

风暴原因及解决方案

  • 场景一
    • 原因过小的复制积压缓冲区(replication backlog)
      当主从节点间的连接断开时,Redis 使用一个固定的缓冲区来保存最近的操作日志,以便支持部分重同步。如果这个缓冲区设置得太小,在高写入量场景下容易被填满,导致只能进行全量同步。
    • 解决方案:根据实际应用场景中的写入频率和允许的最大延迟时间合理设置 repl-backlog-size 参数。一般来说,应该确保该值足以容纳最大预期延迟时间内产生的所有写命令。
  • 场景二
    • 原因从节点数量过多:大量的从节点同时请求全量同步会导致主节点不断的执行 BGSAVE 命令重新生成 RDB 文件,给主节点造成极大的负担。
    • 解决方案:不要一次性添加过多的从节点到单个主节点上。可以通过分层复制结构(即从节点再挂载其他从节点)来分散负载。也是通过修改 replicaof 配置来分散负载,设置参数为另一个从节点的IP。 分层复制

主从复制缺点

  • 复制延时
    由于所有的写操作都是先在 master 上操作,然后同步更新到 slave 上,所以从 master 同步到 slave 机器上有一定的延迟
    当系统很繁忙的时候,延迟问题会更加严重,slave 机器的数量增加也会使这个问题更加严重
  • 主节点挂了,无法自动更新其他从节点为主节点
    默认情况下,当 master 节点挂了,不会在 slave 节点中自动重选一个作为 master ,每次都要人工干预

哨兵模式

哨兵模式简介

Redis的主从复制主要用于实现数据的冗余备份和读分担,并不是为了提供高可用。因此单纯的主从架构无法很好的保证整个系统高可用。

Redis哨兵模式是通过在独立的哨兵节点上运行特定的哨兵进程来实现的。这些哨兵进程监控主从节点的状态,并在发现故障时自动完成故障发现和转移,并通知应用方,实现高可用性。 Redis哨兵模型分析图

哨兵模式原理

节点故障判定流程

  • 心跳检测(PING/PONG)
    每个哨兵节点每秒向所有主节点、从节点和其他哨兵节点发送 PING 命令,检测存活状态。 正常节点会返回 PONG 响应;若节点未在 down-after-milliseconds(默认30秒)内响应,哨兵会标记其进入主观下线(Subjectively Down, SDOWN)状态,即单个哨兵认为某个节点不可用(如网络抖动导致),此时不触发故障转移,仅记录本地状态
  • 客观下线(Objectively Down, ODOWN)
    哨兵通过 SENTINEL is-master-down-by-addr 命令询问其他哨兵对该节点的判断。 当超过 quorum(哨兵配置中定义的最小共识数)的哨兵均认为主节点不可用时,该节点被标记为客观下线,触发故障转移流程

Leader Sentinel 选举流程

主节点被标记为客观下线后,需选举一个 领头哨兵(Leader Sentinel) 来协调故障转移

  • 选举条件
    每个哨兵节点均可发起选举请求,但需满足以下条件:
    • 自身是监控该主节点的哨兵。
    • 当前未参与其他故障转移流程。
  • 投票机制(基于Raft算法)
    发起选举的哨兵向其他哨兵发送 SENTINEL is-master-down-by-addr 命令,附带自己的 epoch(配置版本号) 和 runid,每个 epoch 内仅能投一票,保证同一时间只有一个有效的领头哨兵,防止多个故障转移同时进行,产生脑裂。
    • 其他哨兵遵循先到先得原则,优先响应第一个收到的请求。
    • 若某哨兵获得半数以上(>N/2)的投票,则成为领头哨兵。若未达成共识,等待随机时间后重新发起选举。

故障转移流程

Leader Sentinel 哨兵负责执行故障转移。

  • 筛选新主节点,从所有从节点中选择新主节点,优先级规则:
    • 健康状态:与主节点断开时间不超过 down-after-milliseconds。
    • 复制偏移量:选择数据最新的从节点(复制偏移量最大)。
    • 优先级:配置文件中 slave-priority 值最低的节点优先。
    • Run ID:若上述条件相同,选择字典序最小的 Run ID。
  • 提升新主节点
    领头哨兵向选中的从节点发送 REPLICAOF NO ONE 命令,将其提升为主节点。 等待新主节点完成角色切换,并确认其可写入。
  • 切换从节点
    向其他从节点发送 REPLICAOF new-master-ip new-master-port,使其复制新主节点。
  • 更新客户端配置 哨兵通过发布订阅(Pub/Sub)机制通知客户端新主节点的地址。 客户端监听 +switch-master 事件,自动切换连接。
  • 旧主节点处理 若旧主节点恢复,哨兵会将其降级为从节点,并指向新主节点。

哨兵模式部署

  • 修改配置文件

    shell
    # 88行,修改 bind 项,0.0.0.0 :: 支持所有 IPV4 和 IPV6 远程连接,或修改为 * -::*, 表示含义相同
    bind 0.0.0.0 :: 
    # 端口号 默认
    port 6379
    # 309行,开启守护进程,后台运行
    daemonize yes
    # 357行,指定日志文件目录
    logfile /opt/software/redis/redis-stable/redis.log
    # 514行,指定工作目录
    dir /opt/software/redis
    # 1048行,给默认用户设置密码,主要是使用 redis-cli 连接 redis-server 时,需要通过密码校验。 也可不设置
    requirepass 1qaz@WSX
    # 544行,主节点若降级为从节点时需验证
    masterauth 1qaz@WSX
    shell
    # 88行,修改 bind 项,0.0.0.0 :: 支持所有 IPV4 和 IPV6 远程连接,或修改为 * -::*, 表示含义相同
    bind 0.0.0.0 :: 
    # 端口号 默认
    port 6379
    # 309行,开启守护进程,后台运行
    daemonize yes
    # 357行,指定日志文件目录
    logfile /opt/software/redis/redis-stable/redis.log
    # 514行,指定工作目录
    dir /opt/software/redis
    # 1048行,给默认用户设置密码,主要是使用 redis-cli 连接 redis-server 时,需要通过密码校验。 也可不设置
    requirepass 1qaz@WSX
    # 从节点从主节点拉取数据时需要验证
    masterauth 1qaz@WSX
    # 指向主节点IP和端口 replicaof <主节点IP> <主节点端口>
    replicaof 172.24.57.250 6379
    shell
    # 6行,关闭保护模式
    protected-mode no
    # 10行,指定 Redis Sentinel 监听的端口为 26379。这是默认的 Sentinel 端口,不同于标准 Redis 实例使用的 6379 端口。
    port 26379
    # 15行,指定 Sentinel 为后台启动
    daemonize yes
    # 34行,指定日志存放路径
    logfile /opt/software/redis/redis-stable/sentinel.log
    # 73行,指定工作目录,用于存放临时文件和最终持久化的配置文件。对于 Sentinel 而言,这个目录主要用于存储重新配置客户端时所必需的信息。
    dir /opt/software/redis/sentinel
    # 92行,告诉 Sentinel 去监控名为 mymaster 的主节点,该主节点位于 IP 地址 172.24.57.250,监听端口 6379。数字 2 是 quorum 参数,表示至少需要2个 Sentinel 实例同意认为主节点不可达时,才会真正执行故障转移操作。
    sentinel monitor mymaster 172.24.57.250 6379 2
    # 111行,当主节点设置了密码保护时使用此配置项。这里指定了访问名为 mymaster 的主节点所需的密码为 1qaz@WSX。这样,Sentinel 在与主节点通信时会使用这个密码进行认证。
    sentinel auth-pass mymaster 1qaz@WSX
    # 133行,设置 Sentinel 在认为主节点下线之前等待的时间。这里配置的是如果 3 秒(3000 毫秒)内没有收到主节点的响应,则认为它已经下线
    sentinel down-after-milliseconds mymaster 3000
    # 233行,定义了故障转移超时时间,单位是毫秒。在此期间,Sentinel 将尝试进行故障转移。这个值设为 180000 毫秒(即 3 分钟),意味着在一个故障转移过程中,Sentinel 会在这个时间内不断尝试,直到成功或超时。
    sentinel failover-timeout mymaster 180000
    # 208行,指定在一次故障转移后,允许多少个从节点同时对新的主节点进行同步。这里的配置限制了每次只能有一个从节点进行同步
    sentinel parallel-syncs mymaster 1
  • 重启redis服务以及启动sentinel哨兵

    启动redis服务
    shell
    cd /opt/software/redis/redis-stable
    ./src/redis-server redis.conf
    redis-cli
    auth 1qaz@WSX

    启动Redis服务

    启动sentinel哨兵
    shell
    cd /opt/software/redis/redis-stable
    ./src/redis-sentinel sentinel.conf
    redis-cli
    auth 1qaz@WSX

    启动Sentinel服务

  • 启动后检查哨兵状态

    检查哨兵状态
    shell
    redis-cli -p 26379
    info sentinel

    哨兵状态

  • 故障模拟

    • 停止主节点进程

      shell
      redis-cli
      shell
      # auth 设置的节点密码
      auth 1qaz@WSX
      shutdown
    • 观察哨兵日志 原 172.24.57.250 节点下线,重新选举 172.24.59.168 节点为主节点

      查看哨兵日志
      shell
      cd /opt/software/redis/redis-stable
      cat sentinel.log

      哨兵新一轮选举日志

    • 重新启动 172.24.57.250 节点并观察日志,172.24.57.250 节点加入主从,并成为 172.24.59.168 节点的从节点

      重启 172.24.57.250 节点
      shell
      cd /opt/software/redis/redis-stable
      ./src/redis-server redis.conf

      节点更新为从节点

哨兵使用建议

  • 哨兵节点数量应为多个且为奇数,哨兵本身应该集群,保证高可用。
  • 各个节点如果配置密码,建议保持一致,否则更换主节点后可能由于密码不一致而导致从节点无法从主节点拉取数据甚至无法参与到主从复制的集群中。

集群模式

集群模式简介

Redis集群是由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵,也能完成节点移除和故障转移。Redis集群需要将每个节点设置成集群模式, 这种集群模式没有中心节点,可水平扩展(建议不超过1000个主从群)。Redis集群的性能和高可用性均优于哨兵模式。 集群模式架构图

集群模式原理

数据分片

Redis 集群模式的数据分片(Sharding)通过哈希槽(Hash Slot)机制实现,将数据分散到多个节点存储,解决了单机内存和性能瓶颈的问题。

  • 节点槽位信息:Redis Cluster 将所有数据划分为 16384 个槽位(编号 0~16383),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。节点间通过 Gossip 协议交换槽分配信息,保持一致性。 集群节点信息 nodes-8001.conf 文件位置取决于 redis.conf 中 dir 配置项和 cluster-config-file 配置项 dir配置项cluster-config-file配置项
  • 键到槽的映射
    Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。 HASH_SLOT = CRC16(key) mod 16384。
    • 默认计算规则:对每个键执行 CRC16(key) % 16384,得到该键所属的槽。
    • Hash Tag:通过 {} 指定标签,强制多个键映射到同一槽。例如:
    java
    key1 = "user:{1000}:name"  # 仅计算 CRC16("1000")
    key2 = "user:{1000}:age"   # 同样计算 CRC16("1000")
    这两个键会被分配到同一个槽,支持跨键操作(如事务)。
  • 客户端请求路由
    当 Redis Cluster 的客户端来连接集群时,也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以通过键到槽的映射关系直接定位到目标节点。
    • 客户端缓存槽映射:客户端首次连接集群时获取槽与节点的映射关系。
    • 直接访问:客户端计算键的槽,直接请求对应的节点。
    • 重定向机制
      因为槽位的信息可能会存在客户端与服务器不一致的情况,需要纠正机制来实现槽位信息的校验调整。
      • MOVED 错误:若节点发现请求的槽不属于自己,返回 MOVED slot 目标节点IP:端口,客户端更新缓存并重试。
      • ASK 错误:在迁移过程中,若槽正在迁移,返回 ASK slot 目标节点IP:端口,客户端临时重定向到目标节点。

TIP

shell
mset k1 v1 k2 v2

Redis中的等这样的批量操作命令是具有原子性的,在集群中进行这种批量操作,如果键(k1,k2)对应的槽位都在同一个 master(同一个主从群)下,是没有问题的,可以插入成功。但当所有键不在同一个 master 下时,则操作失败。 not-same-slot

可以通过 Hash Tag 方式,强制多个键映射到同一槽。

节点通信

Redis 集群的节点间通信是集群正常运行的核心机制,通过 Gossip 协议(流言协议)实现去中心化的信息交换,无需依赖固定中心节点,避免单点故障。

  • 目标
    • 维护集群状态的一致性(如节点列表、槽分配、故障状态等)。
    • 自动发现新节点和检测节点故障。
    • 高效传播集群元数据变更(例如槽迁移、节点增减)。
  • 协议类型
  • 通信场景
    • 节点发现与元数据同步
      • 初次加入集群
        • 新节点通过 MEET 消息被现有节点引入。
        • 新节点与现有节点交换 PING/PONG,逐步获取全量集群信息。
      • 元数据更新
        • 节点在 PING 中携带自身视角的集群状态(如槽分配、节点状态)。
        • 接收方合并信息,解决冲突(例如以最新版本号为准)。
    • 故障检测(Failure Detection)
      • 主动探测
        • 节点 A 向节点 B 发送 PING,若超时未收到 PONG,标记节点 B 为 PFAIL(可能故障)。
      • 故障确认
        • 节点 A 在后续 PING 中告知其他节点 B 处于 PFAIL 状态。
        • 若多数主节点确认 B 不可达,触发故障转移,广播 FAIL 消息。
      • FAIL 消息广播
        • FAIL 是唯一使用广播的消息(非 Gossip),确保快速传播。
    • 槽迁移
      • 迁移通知
        • 源节点在 PING 中携带槽迁移状态(如 MIGRATING 标记)。
        • 目标节点在 PING 中携带 IMPORTING 标记。
      • 客户端重定向
        • 节点对迁移中的槽返回 ASK 重定向,客户端临时访问目标节点。

Gossip协议工作原理

  • 基本机制
    • 随机选择通信对象
      • 每个节点每秒随机选择 N 个其他节点发送 PING 消息。
      • 随机性确保信息最终扩散到整个集群。
    • 信息携带
      • PING/PONG 消息中携带部分集群元数据(如节点列表、槽分配、故障标记等)。
      • 每次通信仅携带部分信息,避免网络过载。
    • 最终一致性
      • 通过多次随机传播,集群所有节点最终会达成一致状态。
    • 通信端口
      • 每个节点都有一个专门用于节点间gossip通信的端口,就是自己提供服务的端口号+10000,比如7001,那么 用于节点间通信的就是17001端口。 每个节点每隔一段时间都会往另外几个节点发送ping消息,同时其他几 点接收到ping消息之后返回pong消息。
  • 消息类型
    • PING:主动探测节点状态,携带部分元数据。
    • MEET:邀请新节点加入集群(由管理员触发 CLUSTER MEET)。
    • PONG:对 PING 或 MEET 的响应,同样携带元数据。
    • FAIL:广播消息,快速通知集群某节点不可用(需主节点投票确认)。
    • UPDATE:通知其他节点自身视角的集群配置已更新(如槽迁移完成)。
  • 节点信息更新规则
    • 比较配置纪元(Epoch)
      比如当节点 A 向节点 B 发送 PING 消息时,会携带以下关键信息:
      槽位分配信息:A 视角的槽位分布(例如槽 0~1000 属于节点 X)。
      配置纪元(Config Epoch):一个全局递增的版本号,标识槽位分配的权威性。
      • 若 A 的槽位信息对应的 epoch 大于 B 本地记录的 epoch,B 会 更新自己的槽位信息,并标记为最新。
      • 若 A 的 epoch 小于或等于 B 的本地 epoch,B 忽略 A 的槽位信息。
    • 合并冲突
      • 若 A 和 B 对同一槽位的归属有不同看法,但 epoch 相同,B 会暂时保留自己的信息,等待更高 epoch 的消息到来。

配置纪元

配置纪元(Epoch)是权威依据:值更大的 epoch 代表更新的集群状态。
只有主节点可以更新配置纪元:主节点通过选举或槽迁移操作提升 epoch,避免信息混乱。

Gossip协议与集中式通信的主要区别

对比维度Gossip协议集中式通信
架构设计去中心化;所有节点对等;点对点随机传播;典型应用:Redis集群、Cassandra等中心化;依赖中心节点协调;中心辐射型通信;典型应用:ZooKeeper、Kafka等
可靠性无单点故障;网络分区容忍性高(分区内仍可工作)存在单点故障;网络分区容忍性低(中心节点失联导致瘫痪)
扩展性水平扩展友好,通信开销线性增长(适合数千节点)扩展性受限,中心节点易成瓶颈(适合数百节点内)
一致性模型最终一致性(秒级到分钟级延迟)强一致性(毫秒级到秒级延迟)
实现复杂度高(需处理冲突合并、版本控制、随机传播逻辑)低(中心节点统一决策,逻辑简单)
适用场景高可用、大规模集群、容忍短暂不一致(如状态同步)强一致性、中小规模、快速决策(如分布式锁、选主)

主节点选举原理分析

当 slave 发现自己的 master 变为 FAIL 状态时,在一定的延迟时间之后,便尝试进行 Failover,以期成为新的 master。由于挂掉的 master 可能会有多个slave,从而存在多个 slave 竞争成为 master 节点的过程,其过程如下:

  1. slave 发现自己的 master 变为 FAIL
  2. 将自己记录的集群 currentEpoch 加 1,并广播 FAILOVER_AUTH_REQUEST 信息
  3. 其他节点收到该信息,只有 master 响应,判断请求者的合法性,并发送 FAILOVER_AUTH_ACK,对每一个 epoch 只发送一次 ack
  4. 尝试 failover 的 slave 收集 master 返回的 FAILOVER_AUTH_ACK
  5. slave 收到超过半数 master 的 ack 后变成新 master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)
  6. slave 广播 Pong 消息通知其他集群节点。

WARNING

从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保主节点的FAIL状态在集群中已传播完成,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票 延迟计算公式:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。
这种方式下,持有最新数据的slave将会首先发起选举(理论上)。

脑裂

redis集群没有过半机制会有脑裂问题,网络分区导致脑裂后多个主节点对外提供写服务,一旦网络分区恢复,会将其中一个主节点变为从节点,这时会有大量数据丢失。
规避方法可以在redis.conf配置里加上参数(这种方法不可能百分百避免数据丢失,参考集群leader选举机制):

shell
# 写数据成功最少同步的slave数量,这个数量可以模仿大于半数机制配置,比如集群总共三个节点可以配置1,加上leader就是2,超过了半数
min‐replicas‐to‐write 1

TIP

注意:这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能提供服务了,需要具体场景权衡选择。

集群模式部署

集群部署常用命令

命令
含义
示例
备注
redis-cli --cluster create创建一个新的Redis集群redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 --cluster-replicas 1确保所有指定的节点都已启动;`--cluster-replicas`指定每个主节点的副本数量。
redis-cli --cluster add-node向现有集群添加一个新的节点(通常是主节点)redis-cli --cluster add-node 127.0.0.1:7002 127.0.0.1:7000目标节点必须是未加入任何集群的新节点或已被清空的旧节点。
redis-cli --cluster add-node向现有集群添加一个新的从节点redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000 --cluster-slave使用`--cluster-master-id`指定新从节点应复制的主节点ID。
redis-cli --cluster del-node从集群中移除一个节点redis-cli --cluster del-node 127.0.0.1:7000 <node-id>节点ID可以在`CLUSTER NODES`命令输出中找到;确保节点数据已迁移或不影响集群正常运行。
redis-cli --cluster reshard对集群进行重新分片redis-cli --cluster reshard 127.0.0.1:7000需要指定要移动的槽的数量及目标节点;可能需要手动确认步骤。
redis-cli --cluster rebalance平衡集群中的数据分布redis-cli --cluster rebalance 127.0.0.1:7000可选参数如`--weight`可以用来调整不同节点间的权重分配。
redis-cli --cluster check检查集群的状态redis-cli --cluster check 127.0.0.1:7000提供有关集群健康状态的信息,帮助识别问题。
redis-cli --cluster fix尝试修复集群中的问题redis-cli --cluster fix 127.0.0.1:7000主要用于修复一些特定的问题,比如孤立的主节点。
redis-cli --cluster call在集群的所有节点上执行给定的命令redis-cli --cluster call 127.0.0.1:7000 get key_name不适用于跨多个哈希槽的操作;对于某些命令,可能只在包含相关键的节点上执行。
redis-cli --cluster set-timeout设置集群的节点超时时间redis-cli --cluster set-timeout 127.0.0.1:7000 5000更改此设置可能影响故障检测灵敏度和集群稳定性。
redis-cli --cluster meet手动让两个Redis集群节点互相认识redis-cli --cluster meet 127.0.0.1 127.0.0.2通常自动完成,仅在特殊情况下手动使用。
redis-cli --cluster replicate为指定的主节点分配一个从节点redis-cli --cluster replicate 127.0.0.1:7000 <master-node-id>确保指定的从节点不是其他主节点的副本。
redis-cli --cluster help显示所有可用的`redis-cli --cluster`子命令的帮助信息redis-cli --cluster help获取命令行工具的详细使用说明。

创建集群

Redis集群需要至少三个master节点。目前搭建三个Master,每个主从群下一主一从。每个物理机器下配置两个Redis服务进程,通过不同端口号区分。 集群总线端口(集群节点gossip通信端口)默认为客户端端口 + 10000(如16379),确保防火墙开放此端口。

  • 修改配置文件

    shell
    cd /opt/software/redis
    mkdir redis-cluster
    cd redis-cluster
    mkdir 8001
    mkdir 8002
    shell
    # 309行 开启后台进程启动
    daemonize yes
    # 138行 指定进程端口
    port 8001
    # 341行 把pid进程号写入pidfile配置的文件
    pidfile /var/run/redis_8001.pid
    # 514行 指定数据文件存放位置(不同Redis服务需要指定不同的目录位置,不然会丢失数据指定不同的目录位置,不然会丢失数据)
    dir /opt/software/redis/redis-cluster/8001
    # 1593行 以集群模式启动
    cluster-enabled yes
    # 1601行 集群节点信息文件 名乘客自定义,无需自己创建,redis会自动创建该文件并存储集群节点信息
    cluster-config-file nodes-8001.conf
    # 1607行 在Redis集群中,各个节点会定期发送心跳包(ping)给其他所有节点以检查其状态。
    # 表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项或太短,网络抖动会导致主从频繁切换 (数据的重新复制)。
    # 如果一个节点在 cluster-node-timeout 设定的时间内没有收到另一个节点的心跳回复,它就会标记该节点为疑似下线(PFAIL, Possible Failure)
    cluster-node-timeout 15000
    # 88行 修改绑定网卡IP,允许所有 IPV4 和 IPV6 访问,或修改为 * -::*, 表示含义相同
    bind 0.0.0.0 ::
    # 111行 关闭保护模式
    protected‐mode no
    # 1396行 开启AOF
    appendonly yes
    # 1048行 redis访问密码
    requirepass 1qaz@WSX
    # 544行 集群间各个节点间的访问密码,跟上面一致
    masterauth 1qaz@WSX
    # 当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,如果为yes则集群不可用
    cluster-require-full-coverage no
  • 启动Redis服务 分别单独启动每个Redis服务

    启动Redis服务
    shell
    cd /opt/software/redis/redis-stable
    # redis.conf 根据实际的文件名进行更换
    ./src/redis-server redis.conf
  • 创建集群 使用redis-cli自动分配主从节点和槽位

    创建集群
    shell
    redis-cli -a 1qaz@WSX --cluster create \
    8.152.192.252:8001 \
    47.94.43.198:8001 \
    39.107.57.146:8001 \
    8.152.192.252:8002 \
    47.94.43.198:8002 \
    39.107.57.146:8002 \
    --cluster-replicas 1 \
    --cluster-yes  # 自动确认槽位分配(可选)
    • --cluster-replicas 1:每个主节点分配1个从节点(前3个节点为主节点,后3个为从节点)。
    • 若配置了密码,需添加参数 -a your_password。
  • 验证集群状态

    shell
    # 连接任意节点
    redis-cli -c -h 8.152.192.252 -p 8001
    shell
    # 密码确认
    auth 1qaz@WSX
    # 查看节点信息
    cluster nodes
    # 检查槽位分配
    cluster slots

    cluster-nodes

集群水平扩容

  • 原始集群状态及信息
    origin-cluster-info
  • 启动新的redis服务
    在 39.107.57.146、47.94.43.198、8.152.192.252 分别新启动一个 redis 服务,端口号为 8003,别忘记关闭防火墙或开启对应的服务端口 8003,Gossip通信端口 1000 + port,即 18003 端口
    shell
    cd /opt/software/redis/redis-cluster
    mkdir 8003
    shell
    cd /opt/software/redis/redis-stable
    ./src/redis-server redis-cluster-8003.conf
  • 添加主节点
    使用 add-node 命令新增一个主节点 8.152.192.252:8003(master),前面的 ip:port 为新增节点,后面的 ip:port 为集群中已知存在节点,看到日志最后有 [OK] New node added correctly 代表新节点加入成功
    添加新节点
    shell
    redis-cli -a 1qaz@WSX --cluster add-node 8.152.192.252:8003 39.107.57.146:8001
    add-master-node

    TIP

    注意:当添加节点成功以后,新增的节点不会有任何数据,因为它还没有分配任何的 slot(hash槽),我们需要为新节点手工分配 hash 槽

    cluster-add-info
  • 为新主节点分配槽位 注意槽位分配命令中对应的IP端口号是已在集群中并已被分配槽位的任一主节点即可
    槽位分配
    shell
    redis-cli -a 1qaz@WSX --cluster reshard 39.107.57.146:8001
    cluster-resharedexecute-reshared
  • 查看最新主节点槽位信息
    查看最新主节点槽位信息
    shell
    cd /opt/software/redis/redis-cluster/8003/
    cat nodes-8003.conf
    new-cluster-info-reshared 如上图所示,目前 8.152.192.252:8003 redis节点已经有hash槽了,也就是说可以在 8.152.192.252:8003 上进行读写数据啦!到此为止我们的 8.152.192.252:8003 已经加入到集群中,并且是主节点(Master)
  • 为新主节点添加从节点
    为新主节点添加从节点
    shell
    # 39.107.57.146:8003 新节点的IP和端口 8.152.192.252:8003 集群中任一节点IP和端口即可 4bcc1175b009856971cd510ffdd41d806e9ebdd6 新的主节点的ID,可查看 nodes-*.conf 文件或通过操作 redis-cli 客户端执行 cluster nodes 命令查看 
    redis-cli -a 1qaz@WSX --cluster add-node 39.107.57.146:8003 8.152.192.252:8003 --cluster-slave --cluster-master-id 4bcc1175b009856971cd510ffdd41d806e9ebdd6
    redis-cli -a 1qaz@WSX --cluster add-node 47.94.43.198:8003 8.152.192.252:8003 --cluster-slave --cluster-master-id 4bcc1175b009856971cd510ffdd41d806e9ebdd6
    add-cluster-slave
  • 查看集群节点信息
    查看集群节点信息
    shell
    cd /opt/software/redis/redis-cluster/8003/
    cat nodes-8003.conf
    cluster-new-slave-info 可以看到两个新节点已加入集群,并做为了指定节点的从节点