Redis学习笔记:Cluster 分片集群从原理到实战部署
本文首发于 栏轩·阁欢迎访问阅读原文获取更好的阅读体验。一、什么是 Redis ClusterRedis Cluster 是 Redis官方提供的分布式解决方案从 Redis 3.0 开始引入。它通过数据分片Sharding和自动故障转移Failover实现了水平扩展将数据自动分布到多个节点高可用性部分节点故障时集群仍可正常工作去中心化架构无中心代理节点所有节点通过 Gossip 协议通信解决了什么问题问题说明单机容量瓶颈单个 Redis 实例最多存储几个 GB 到几十 GB 数据Cluster 可以将数据分散到多台机器单点故障主节点宕机后从节点自动晋升无需人工干预读写压力多主节点并行处理请求写入吞吐量线性提升扩容困难传统方式需要停机迁移数据Cluster 支持在线动态扩缩容二、Redis 部署方案对比特性单机实例主从复制Sentinel 哨兵Cluster 分片集群数据容量受单机内存限制受单机内存限制受单机内存限制可扩展至多台机器写入性能单点写入单点写入主单点写入主多主写入线性扩展自动故障转移❌❌✅✅自动分片❌❌❌✅在线扩缩容❌❌❌✅配置复杂度⭐ 简单⭐⭐⭐⭐⭐⭐⭐⭐⭐适用场景开发/缓存读写分离高可用场景大规模高可用场景什么时候选择 Cluster数据量超过单机内存建议单机 ≤ 16GB需要高写入吞吐量要求自动故障转移和高可用性希望在线扩缩容避免停机注意如果数据量小且不需要高可用单机或 Sentinel 更简单高效。Cluster 的事务和 Lua 脚本仅支持同一槽位的 Key。三、核心架构原理3.1 哈希槽Hash SlotRedis Cluster没有采用一致性哈希而是使用固定 16384 个哈希槽Hash SlotCRC16(key) % 16384 → 所属槽位每个 Key 通过CRC16算法计算出哈希值对 16384 取模得到槽号每个节点负责一段连续的槽位范围新增/移除节点时只需迁移槽位不需要 rehash 所有数据为什么是 16384 个槽Redis 作者在 FAQ 中解释过16384 个槽用 2KB 的空间即可在节点间传递完整的槽位信息16384 bit ÷ 8 ÷ 1024 2KB而 65535 个槽则需要 8KB在网络开销和灵活性之间取得了平衡。3.2 Gossip 协议Cluster 节点间通过Gossip八卦协议通信每个节点每秒随机选择 5 个节点发送PING交换节点状态、槽位信息、主从关系如果收到PONG超时标记节点为PFAIL可能故障当多数主节点都标记某个节点为PFAIL升级为FAIL并触发故障转移这种去中心化设计意味着没有单点瓶颈但最终一致性意味着短时间内节点间可能存在信息不一致。3.3 主从架构每个主节点Master可以有 1 个或多个从节点Slave主节点负责处理读写请求和槽位数据从节点异步复制主节点数据主节点宕机时选举晋升建议为每个主节点至少配置一个从节点保证高可用四、环境搭建Docker Compose下面我们用 Docker Compose 启动6 个 Redis 节点3 主 3 从这是生产推荐的最小集群配置。version:3.8services:redis-node-1:image:redis:7.2.4container_name:redis-cluster-1command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6379:6379-16379:16379networks:-cluster-netredis-node-2:image:redis:7.2.4container_name:redis-cluster-2command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6380:6379-16380:16379networks:-cluster-netredis-node-3:image:redis:7.2.4container_name:redis-cluster-3command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6381:6379-16381:16379networks:-cluster-netredis-node-4:image:redis:7.2.4container_name:redis-cluster-4command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6382:6379-16382:16379networks:-cluster-netredis-node-5:image:redis:7.2.4container_name:redis-cluster-5command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6383:6379-16383:16379networks:-cluster-netredis-node-6:image:redis:7.2.4container_name:redis-cluster-6command:redis-server--port 6379--cluster-enabled yes--cluster-config-file nodes.conf--cluster-node-timeout 5000--appendonly yes--bind 0.0.0.0ports:-6384:6379-16384:16379networks:-cluster-netnetworks:cluster-net:driver:bridge配置参数详解参数含义--cluster-enabled yes启用集群模式--cluster-config-file nodes.conf集群自动生成的配置文件不需要手动创建--cluster-node-timeout 5000节点超时时间ms超时被视为故障--appendonly yes开启 AOF 持久化--bind 0.0.0.0允许来自所有网络接口的连接16379端口集群总线端口数据端口 10000用于节点间 Gossip 通信五、创建分片集群5.1 启动容器docker-composeup-d5.2 创建集群进入任意一个容器并执行创建命令# 进入容器dockerexec-itredis-cluster-1sh# 创建集群注意这里用的是容器名不是 IPredis-cli--clustercreate\redis-cluster-1:6379\redis-cluster-2:6379\redis-cluster-3:6379\redis-cluster-4:6379\redis-cluster-5:6379\redis-cluster-6:6379\--cluster-replicas1命令解析--cluster-replicas 1每个主节点分配 1 个从节点总共 6 个节点 → 3 主 3 从如果不加这个参数6 个节点全为主节点不推荐无高可用执行后 Redis 会打印槽位分配方案并让你确认输入yes继续。5.3 参考输出 Performing hash slots allocation on 6 nodes... Master[0] - Slots 0 - 5460 Master[1] - Slots 5461 - 10922 Master[2] - Slots 10923 - 16383 Adding replica redis-cluster-4:6379 to redis-cluster-1:6379 Adding replica redis-cluster-5:6379 to redis-cluster-2:6379 Adding replica redis-cluster-6:6379 to redis-cluster-3:6379 ... [OK] All 16384 slots covered.看到[OK] All 16384 slots covered.表示所有 16384 个槽位分配完毕集群创建成功。六、验证集群状态6.1 查看节点信息dockerexec-itredis-cluster-1 redis-cli cluster nodes输出示例16beb014f42bf997e7e9dc40e4a03d96588ca2f7 172.23.0.5:637916379 master - 0 1784104659539 2 connected 5461-10922 c2c4b89c1359f8b7fc200fb9fb3f5e591132461c 172.23.0.4:637916379 myself,master - 0 1784104658000 1 connected 0-5460 ff93232a5b0ce6abfd4c04dad4e778e47cf19d45 172.23.0.2:637916379 slave 16beb014f42bf997e7e9dc40e4a03d96588ca2f7 0 1784104659000 2 connected d098439d4b4ad4a461777737e7ea2ab2d9591d1b 172.23.0.7:637916379 slave c2c4b89c1359f8b7fc200fb9fb3f5e591132461c 0 1784104659640 1 connected 5089042042bcc6ad2edf0b6dc07d5721c0c4fcf5 172.23.0.6:637916379 slave 7556fed402a74a5dd377365e16d41253d2e1ee99 0 1784104658000 3 connected 7556fed402a74a5dd377365e16d41253d2e1ee99 172.23.0.3:637916379 master - 0 1784104659000 3 connected 10923-16383字段解读字段示例含义节点 ID16beb0...节点唯一标识持久化到 nodes.conf地址172.23.0.5:637916379数据端口集群总线端口角色master/slave主节点或从节点主节点 ID如16beb0...slave 行该从节点所属的主节点连接状态myself,master当前连接的节点是自己槽位范围0-5460该节点负责的哈希槽范围6.2 集群完整性检查dockerexec-itredis-cluster-1 redis-cli--clustercheck redis-cluster-1:6379输出[OK] All nodes agree about slots configuration. Check for open slots... Check slots coverage... [OK] All 16384 slots covered.七、数据读写与 MOVED 重定向7.1 不使用集群模式dockerexec-itredis-cluster-1 redis-clisetfoo bar返回(error) MOVED 12182 172.23.0.3:6379为什么会这样这个错误是 Redis Cluster 的典型行为客户端向redis-cluster-1发送SET foo barRedis 对foo计算哈希槽CRC16(foo) % 16384 12182redis-cluster-1不负责 12182 号槽它负责 0-5460它知道负责该槽的节点是172.23.0.3:6379返回MOVED错误客户端应该重定向到正确节点执行命令7.2 使用集群模式-c 参数# 写入dockerexec-itredis-cluster-1 redis-cli-csetfoo bar# 读取不需要在特定节点读dockerexec-itredis-cluster-3 redis-cli-cget foo-ccluster 模式让redis-cli自动跟随 MOVED 重定向透明地连接到正确的节点执行命令。生产建议应用代码中应使用支持 Cluster 的 Redis 客户端如redis-py-cluster、Lettuce、JedisCluster它们会自动处理 MOVED 重定向和槽位缓存。7.3 查看 Key 的哈希槽dockerexec-itredis-cluster-1 redis-cli CLUSTER KEYSLOT foo# 返回: (integer) 121827.4 查询所有槽位分布dockerexec-itredis-cluster-1 redis-cli CLUSTER SLOTS输出示例1) 1) (integer) 0 -- 起始槽位 2) (integer) 5460 -- 结束槽位 3) 1) 172.23.0.2 -- 主节点 IP 2) (integer) 6379 3) node_id_1 4) 1) 172.23.0.5 -- 从节点 IP 2) (integer) 6379 3) node_id_4 2) 1) (integer) 5461 2) (integer) 10922 3) 1) 172.23.0.3 2) (integer) 6379 ...八、故障转移8.1 手动模拟故障关闭一个主节点观察从节点自动晋升# 停止一个主节点比如 redis-cluster-1它负责 0-5460 槽dockerstop redis-cluster-1# 稍等片刻默认超时 5 秒查看集群状态dockerexec-itredis-cluster-2 redis-cli cluster nodes可以看到原本redis-cluster-1的从节点如172.23.0.2:6379已经晋升为master。8.2 故障转移原理主节点宕机后从节点检测到PING超时从节点等待集群超时时间cluster-node-timeout默认 5 秒通过Raft 类似算法发起选举获得多数主节点投票后晋升为新主节点接管原主节点的所有槽位8.3 恢复原主节点# 重启之前关闭的节点dockerstart redis-cluster-1# 它会以从节点身份重新加入集群成为新主节点的副本九、Hash Tag将关联 Key 存入同一槽位9.1 为什么需要 Hash TagRedis Cluster 的事务MULTI/EXEC和Lua 脚本要求所有操作的 Key必须在同一个哈希槽否则会报错(error) CROSSSLOT Keys in request dont hash to the same slot同时批量操作MGET/MSET跨节点也有额外的网络开销。9.2 Hash Tag 语法Key 中{...}部分只使用花括号内的内容计算哈希槽# 这两个 Key 都会用 user:1 计算哈希槽 {user:1}:name {user:1}:age9.3 验证# 查看两个 Key 的哈希槽注意不加 -c 不会自动重定向但 KEYSLOT 命令不受影响dockerexec-itredis-cluster-1 redis-cli CLUSTER KEYSLOT{user:1}:namedockerexec-itredis-cluster-1 redis-cli CLUSTER KEYSLOT{user:1}:age两个命令返回相同的槽位号。9.4 实际使用# 写入关联 Keydockerexec-itredis-cluster-1 redis-cli-cset{user:1}:name Alicedockerexec-itredis-cluster-1 redis-cli-cset{user:1}:age30# 批量读取在同一槽位效率更高dockerexec-itredis-cluster-1 redis-cli-cmget{user:1}:name{user:1}:age9.5 使用场景场景说明事务操作MULTI/EXEC需要所有 Key 在同一槽位Lua 脚本EVAL脚本中所有 Key 必须在同一槽位批量读写MGET/MSET跨槽位需要多次网络请求关联数据用户信息、订单明细等高关联度数据十、总结与最佳实践关键要点Cluster 适用场景数据量大、写入吞吐高、需要自动故障转移的大规模 Redis 部署最小生产配置6 节点3 主 3 从每个主节点至少一个副本客户端必须支持 Cluster使用-c模式或集成 Cluster 客户端库事务限制MULTI/EXEC 和 Lua 脚本需要配合 Hash Tag{...}节点数建议主节点数量通常为奇数方便选举投票建议 3、5、7 个注意事项网络延迟跨节点操作比单节点慢合理设计 Key 分布批量操作尽量用 Hash Tag 让关联 Key 落在同一槽位扩缩容生产环境扩缩容时关注槽位迁移对性能的影响监控重点关注cluster_state、cluster_slots_ok、cluster_known_nodes等指标

相关新闻

BrowserOS Neo 核心能力与实战表现深度评测

BrowserOS Neo 核心能力与实战表现深度评测

在开发复杂 Web 应用或进行高强度多任务办公时,浏览器早已不再仅仅是一个简单的页面查看器,它更像是一个轻量级的操作系统。很多开发者在日常工作中都会遇到这样的尴尬场景:本地调试时一切正常,一旦开启十几个标签页同时运行多个微…

2026/10/16 1:29:03 阅读更多 →
java 序列化总结和分类

java 序列化总结和分类

Java序列化是将对象状态转换为字节流的技术,用于数据持久化和网络传输,是分布式系统的基石。以下从工具、方法、实践、对比、场景到高阶应用,为你全面梳理。 一、Java序列化工具全景图 Java序列化工具按数据格式和应用场景可分为三大类: 分类 代表工具 数据格式 核心特点 …

2026/10/15 13:23:15 阅读更多 →
终极NVIDIA显卡优化指南:免费开源工具解锁隐藏性能

终极NVIDIA显卡优化指南:免费开源工具解锁隐藏性能

终极NVIDIA显卡优化指南:免费开源工具解锁隐藏性能 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为游戏卡顿、画面撕裂而烦恼吗?想要让显卡发挥最大潜力却不知从何下手&am…

2026/10/11 19:24:55 阅读更多 →

最新新闻

Mac mini + OpenClaw 打造 7×24 小时个人 AI 助手:部署与成本全攻略

Mac mini + OpenClaw 打造 7×24 小时个人 AI 助手:部署与成本全攻略

自从把家里的 Mac mini 改造成 724 小时在线的 AI 助手,已经稳定跑了几个月。这个组合其实很简单:一台常年开机的 Mac mini,一个开源的智能体框架 OpenClaw,再接入按量计费的模型 API——很多人也叫它中转 API。整套方案算下来&am…

2026/10/16 5:03:29 阅读更多 →
STM32 GPS定位OLED显示:从NMEA解析到上屏的完整工程链路实践

STM32 GPS定位OLED显示:从NMEA解析到上屏的完整工程链路实践

简介:面向物联网、车载导航与户外运动设备等应用场景,这份资料提供了一套基于STM32微控制器的GPS定位系统开发方案。内容以STM32与GPS模块的串口通信、NMEA协议解析及OLED实时显示为核心,适合正在学习嵌入式定位技术的中初级开发者。压缩包共…

2026/10/16 5:03:29 阅读更多 →
JS对象从创建到原理:原型链、属性描述符与深浅拷贝实战

JS对象从创建到原理:原型链、属性描述符与深浅拷贝实战

作为一个整天跟 JavaScript 打交道的前端开发,我越来越觉得,对象这东西就是 JS 的命根子。你要是能把对象搞透,什么框架、源码、工程化,看着都跟玩拼图似的。但我也发现,很多写了两年多的开发者,对象还停留在“{ } 存东…

2026/10/16 5:03:29 阅读更多 →
OpenCode 限流报错全解析:从原因定位到修复的工程实践

OpenCode 限流报错全解析:从原因定位到修复的工程实践

1. 限流报错背后的真实逻辑1.1 这个报错到底在说什么Rate limit exceeded这个报错,字面意思就是“请求速率超出限制”。但很多人第一次看到它的时候会懵——明明自己只是正常调用接口,怎么就被限流了?我刚开始接触 OpenCode 这类 AI 编程辅助…

2026/10/16 5:03:29 阅读更多 →
MP2642GR-Z+ATmega1280双电池主动均衡设计实战

MP2642GR-Z+ATmega1280双电池主动均衡设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:03:29 阅读更多 →
从SDK Demo到稳定流水线:海康相机二次开发实战解析

从SDK Demo到稳定流水线:海康相机二次开发实战解析

简介:海康相机SDK二次开发资料包,专注于MvCodeReader模块在快递包裹一维码识别与XY坐标获取上的应用,面向需要部署物流自动分拣、实时扫码定位系统的.NET开发者。资源共41个文件,压缩包大小486KB,内含8个C#源文件、2个…

2026/10/16 5:02:29 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →