摘要:本文介绍了Redis的集群模式。
环境
Windows 10 企业版 LTSC 21H2
Redis 7.4.8
1 概述
集群模式(Cluster)是Redis的一种高可用方案,它将数据分布在多个节点上,实现数据的自动分片和高可用性。
相对于哨兵模式,集群模式不仅支持自动故障转移,还实现了数据的自动分片,提高了系统的横向扩展能力。
集群模式是Redis官方推荐的高可用方案,适用于大规模生产环境。
2 作用
集群模式的作用:
- 数据分片:将数据自动分布在多个节点上,提高系统的存储容量。
- 横向扩展:可以通过添加节点来扩展集群的容量和性能。
- 负载均衡:自动将请求分发到不同的节点,提高系统的整体性能。
- 故障转移:当集群中的主节点发生故障时,自动将从节点升级为主节点。
- 高可用:当部分节点发生故障时,集群仍然可以正常工作。
3 原理
3.1 数据分片
集群采用哈希槽(Hash Slot)的方式进行数据分片:
- 整个集群共有16384个哈希槽。
- 每个键通过CRC16算法计算哈希值,然后对16384取模,得到对应的哈希槽。
- 每个节点负责一部分哈希槽。
3.2 节点类型
集群中的节点分为两种类型:
- 主节点:负责处理读写请求,维护哈希槽。
- 从节点:作为主节点的备份,当主节点发生故障时可以升级为主节点。
对于主节点来说,存在两种特殊情况:
- 孤立主节点:指的是只有哈希槽,没有从节点的主节点,有数据但是缺少从节点。
- 空壳主节点:指的是没有哈希槽,只有从节点的主节点,无数据所以从节点闲置。
3.3 通信机制
集群中的节点通过Gossip协议进行通信:
- 节点定期随机向其他节点发送
PING消息,包含自身状态和集群信息。 - 其他节点回复
PONG消息,更新本地集群状态。
通过Gossip协议,集群可以快速传播状态变化,保持一致性。
3.4 故障转移
当主节点发生故障时,集群会自动进行故障转移:
- 从节点检测到主节点故障,标记为
PFAIL表示可能故障。 - 超过半数的从节点确认主节点故障,标记为
FAIL表示确定故障。 - 从节点之间进行投票,选举新的主节点。
- 新的主节点接管原主节点的哈希槽。
- 新的主节点向集群广播更新拓扑结构,通知其他节点。
3.5 资格检查
当主节点发生故障时,如果从节点发现自身数据过于陈旧,会避免发起故障转移,不参与主节点的选举。
为了衡量从节点的数据是否过期,节点会根据超时时间 * 检查因素 + 交互周期来计算节点的过期时间,如果从节点与主节点最后交互的时间超过这个时间,从节点会放弃尝试故障转移。
对于能够参与故障转移的从节点,会根据复制偏移量排序,复制偏移量越大,说明数据越新,成为主节点的概率越高。
3.6 客户端支持
为了简化客户端的使用,许多高级客户端(Jedis、Lettuce)实现了智能客户端(Smart Client)的功能,它能够:
- 缓存槽位映射:首次连接时,从集群中获取并缓存槽位和节点的映射关系。
- 自动计算槽位:计算键对应的槽位,将请求发往正确的节点,避免重定向开销。
- 自动更新拓扑:当集群拓扑发生变化时,客户端能感知并更新本地的槽位映射。
- 自动重定向:自动处理MOVED和ASK(槽位迁移中的临时重定向)错误。
4 配置
修改每个节点的redis.conf配置文件,启用集群模式:
1 | # 启用集群模式 |
5 搭建
5.1 准备节点
准备6个Redis节点,用于实现3主3从集群架构。
打开redis.conf配置文件,修改端口号并开启集群模式:
1 | # 修改端口号 |
启动6个Redis节点。
5.2 创建集群
语法:
1 | redis-cli --cluster create 节点IP地址:节点端口号 ... 节点IP地址:节点端口号 --cluster-replicas 1 --cluster-yes |
说明:
--cluster-replicas 1:表示每个主节点都有1个从节点。--cluster-yes:表示自动确认创建集群,不需要手动确认。
示例:
1 | redis-cli --cluster create 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 127.0.0.1:6386 --cluster-replicas 1 --cluster-yes |
执行成功后,集群自动分配槽位并完成主从绑定。
5.3 检查集群
语法:
1 | redis-cli --cluster check 节点IP地址:节点端口号 |
示例:
1 | redis-cli --cluster check 127.0.0.1:6381 |
5.4 查看信息
语法:
1 | redis-cli --cluster info 节点IP地址:节点端口号 |
示例:
1 | redis-cli --cluster info 127.0.0.1:6381 |
6 状态监控
6.1 连接集群
使用命令连接集群节点:
1 | redis-cli -c -h 127.0.0.1 -p 6381 |
6.2 查看基本信息
使用命令查看集群的基本信息:
1 | CLUSTER INFO |
显示结果:
cluster_state:ok:集群状态,ok表示正常cluster_slots_assigned:16384:已分配的哈希槽数量cluster_slots_ok:16384:状态正常的哈希槽数量cluster_slots_pfail:0:可能失败的哈希槽数量cluster_slots_fail:0:确认失败的哈希槽数量cluster_known_nodes:6:已知的节点数量,包括主节点和从节点cluster_size:3:主节点数量cluster_current_epoch:6:当前纪元,用于故障转移和节点选举,值越大说明发生变更的次数越多cluster_my_epoch:1:当前节点的纪元cluster_stats_messages_ping_sent:541:发送的PING消息数量cluster_stats_messages_pong_sent:562:发送的PONG消息数量cluster_stats_messages_sent:1103:发送的消息总数cluster_stats_messages_ping_received:557:接收的PING消息数量cluster_stats_messages_pong_received:541:接收的PONG消息数量cluster_stats_messages_meet_received:5:接收的MEET消息数量cluster_stats_messages_received:1103:接收的消息总数
6.3 查看节点状态
使用命令查看集群的节点状态:
1 | CLUSTER NODES |
6.4 查看哈希槽分配
使用命令查看集群的哈希槽分配:
1 | CLUSTER SLOTS |
7 集群管理
7.1 迁移槽位
语法:
1 | redis-cli --cluster reshard 节点IP地址:节点端口号 |
说明:
--cluster-from 源节点ID,...,源节点ID:指定要迁移的源节点ID,多个节点用逗号分隔,使用all表示全部节点平均迁移。--cluster-to 目标节点ID:指定要迁移的目标节点ID。--cluster-slots 迁移槽位数量:指定要迁移的槽位数量。--cluster-yes:表示自动确认迁移槽位,不需要手动确认。
如果不使用参数,会通过交互方式迁移槽位。
7.2 平衡集群
语法:
1 | redis-cli --cluster rebalance 节点IP地址:节点端口号 |
说明:
--cluster-use-empty-masters:把槽位分配给当前没有槽位的主节点,扩容后负载均衡的常用选项。--cluster-weight 节点ID=权重 ... 节点ID=权重:根据权重分配槽位给节点,权重支持整数和浮点数。--cluster-threshold 百分比:设置触发平衡的阈值,避免微小波动引起不必要的数据迁移,只有节点槽位偏离平均值超过阈值时才会触发平衡,默认是2。--cluster-simulate:模拟执行模式,显示将要执行的数据迁移计划,是生产环境操作前进行安全评估的首选工具。
如果不使用参数,只会平衡已有槽位并且偏离平均值2%的主节点,不会处理空节点。
7.3 添加节点
语法:
1 | redis-cli --cluster add-node 新节点IP地址:新节点端口号 现有节点IP地址:现有节点端口号 |
说明:
--cluster-slave:表示添加从节点,默认添加主节点。--cluster-master-id 主节点ID:指定主节点的ID,默认随机主节点。
添加主节点后,需要迁移槽位或者平衡集群。
7.4 删除节点
语法:
1 | redis-cli --cluster del-node 现有节点IP地址:现有节点端口号 删除节点ID |
删除主节点之前,需要先将主节点的槽位分配给其他节点。
8 故障转移
8.1 自动故障转移
主节点宕机后,等待超时之后,集群自动发起故障选举,将从节点升级为主节点并接管槽位。
整个过程可能会丢失在主节点宕机前尚未同步给从节点的数据。
8.2 手动故障转移
在从节点上执行命令:
1 | CLUSTER FAILOVER |
从节点会与主节点进行一次数据同步,确保数据与主节点一致,然后发起切换,从节点先向集群宣布自己将要成为主节点,然后集群会将旧主节点降级为从节点并重新分配槽位。
整个过程中不会丢失已确认写入的数据,能够保证数据一致性,如果主节点宕机,命令直接报错,不会触发任何切换。
8.3 强制故障转移
在从节点上执行命令:
1 | CLUSTER FAILOVER FORCE |
从节点不等待数据同步,立即发起切换,从节点立刻升级为主节点并接管旧主节点所有槽位,旧主节点会降级为从节点并使用新主节点的数据。
整个过程可能会丢失未同步给从节点的数据,建议在主节点宕机时使用。
9 最佳实践
建议部署至少6个节点,形成3主3从的集群架构,以保证高可用性。
所有节点的硬件配置应尽可能一致,以保证集群的性能均衡。
条