【Redis】实操:cluster集群部署

news/2025/11/4 21:07:34/文章来源:https://www.cnblogs.com/zmxhello/p/19191372

Redis Cluster 基于docker-compose的部署

前言

Redis 作为高性能的键值存储,在生产环境中需通过集群方案保障高可用与水平扩展。Redis 提供的三种核心高可用方案:

  • 主从模式:一个主节点写,从节点读,解决读扩展,但主节点故障需手动切换。
  • 哨兵模式:在主从基础上加入 Sentinel,提供主节点故障自动切换,实现高可用,但仍是单节点写。
  • 集群模式:分布式架构,通过分片支持多主多从,解决容量和写压力,同时支持自动 failover,实现高可用和水平扩展。

主从复制仅解决数据备份问题,哨兵 虽实现故障自动转移但无法横向扩展存储,而 Redis Cluster 同时支持数据分片(Sharding) 与自动故障转移,是应对大规模数据与高并发场景的最优选择-也是官方推荐的部署方式

之前总是理论上学习redis集群模式,有主从复制、哨兵、cluster,目的都是为了实现redis的高可用性。
现在动手基于docker在本地部署一个 3主3从集群,适用于开发、测试及小型生产环境的集群搭建参考,以更好理解redis集群的工作模式。

环境

  • docker-compose: v27.5.1
  • OS: Mac-m2
  • Redis 镜像: redis:7-alpine

工作目录

redis-cluster/
├── redis-cluster/
│   ├── redis1.conf
│   ├── redis2.conf
│   ├── redis3.conf
│   ├── redis4.conf
│   ├── redis5.conf
│   └── redis6.conf
└── docker-compose.yaml

规划与配置

集群架构设计

本次部署采用 3 主 3 从 架构,核心设计原则如下:

  • 主节点(Master):负责数据写入、槽位(Slot)管理,3 个主节点平均分配 16384 个槽位(0-5460、5461-10922、10923-16383)。
  • 从节点(Slave):每个主节点对应 1 个从节点,实时同步主节点数据,主节点故障时自动升为新主,保障高可用。

配置

每台redis实例的配置大部分相同,以redis1举例

bind 0.0.0.0
protected-mode no
port 6379cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 172.20.1.1
cluster-announce-port 6379
cluster-announce-bus-port 16379maxmemory 1024mb
maxmemory-policy allkeys-lruappendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mbsave 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdbtcp-keepalive 300
tcp-backlog 511
timeout 0
databases 16cluster-require-full-coverage no
cluster-replica-validity-factor 10
cluster-migration-barrier 1

docker-compose.yaml

version: '3.8'networks:lufy-cluster:driver: bridgeipam:config:- subnet: 172.20.0.0/16
volumes:redis-cluster-data:services:# Redis集群节点1redis-cluster-1:image: redis:7-alpine  # 轻量级Redis镜像container_name: lufy-redis-cluster-1ports:- "8000:6379"        # 本地端口8000映射容器6379(客户端访问用)- "18000:16379"      # 集群总线端口volumes:- ./redis-cluster/redis1.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.1  # 固定IP 确保初始化能找到节点restart: unless-stopped# Redis集群节点2redis-cluster-2:image: redis:7-alpinecontainer_name: lufy-redis-cluster-2ports:- "8001:6379"- "18001:16379"volumes:- ./redis-cluster/redis2.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.2restart: unless-stopped# Redis集群节点3redis-cluster-3:image: redis:7-alpinecontainer_name: lufy-redis-cluster-3ports:- "8002:6379"- "18002:16379"volumes:- ./redis-cluster/redis3.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.3restart: unless-stopped# Redis集群节点4(从节点候选)redis-cluster-4:image: redis:7-alpinecontainer_name: lufy-redis-cluster-4ports:- "8003:6379"- "18003:16379"volumes:- ./redis-cluster/redis4.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.4restart: unless-stopped# Redis集群节点5(从节点候选)redis-cluster-5:image: redis:7-alpinecontainer_name: lufy-redis-cluster-5ports:- "8004:6379"- "18004:16379"volumes:- ./redis-cluster/redis5.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.5restart: unless-stopped# Redis集群节点6(从节点候选)redis-cluster-6:image: redis:7-alpinecontainer_name: lufy-redis-cluster-6ports:- "8005:6379"- "18005:16379"volumes:- ./redis-cluster/redis6.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confnetworks:lufy-cluster:ipv4_address: 172.20.1.6restart: unless-stopped

关键参数说明

  • cluster-enabled yes yes/no 启用 Redis Cluster 模式(必开,否则为单机模式)
  • cluster-config-file nodes.conf nodes.conf 集群节点信息自动生成文件(容器内路径,无需手动编辑,重启后自动更新)
  • cluster-node-timeout 15000 15000(毫秒) 节点超时时间,超过此时间未通信则判定为故障(建议 10-30s,避免误判)
  • cluster-announce-ip 172.20.1.1 容器固定 IP 集群内节点间通信的 IP(必须为容器在自定义网络中的固定 IP,否则跨节点无法发现)
  • cluster-announce-port 6379 6379 客户端访问端口(对外提供服务)
  • cluster-announce-bus-port 16379 16379 集群总线端口(节点间心跳、故障检测、配置同步,需与客户端端口差 10000)
  • cluster-require-full-coverage no yes/no 是否要求所有槽位可用才提供服务(生产建议 no,部分槽位故障不影响其他槽位)
  • cluster-migration-barrier 1 1 主节点保留的最小从节点数(低于此数不允许从节点迁移,保障高可用)

启动

cd redis-cluster
docker compose up -d
# 验证状态,此时应该有6个redis实例启动
docker ps

但是此时,每个实例之间并没有进行集群、主从连接,需要执行初始化命令:

# 挑选前 3 个作为主节点候选(当然也可以手动创建 指定主节点)
docker exec -it lufy-redis-cluster-1 redis-cli --cluster create 172.20.1.1:6379 172.20.1.2:6379 172.20.1.3:6379 172.20.1.4:6379 172.20.1.5:6379 172.20.1.6:6379 --cluster-replicas 1 --cluster-yes

输出有下面的关键信息说明集群搭建成功:

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

测试

1.基础验证

因为对于集群模式,很突出的特点是去中心化,只要连接集群中任意一个redis实例即可操作整个集群。
比如,进入redis1实例的容器,查看集群状态:

docker exec -it lufy-redis-cluster-1 redis-cli -c -p 6379 cluster nodes

连接其中一个实例:

# 进入启动的 lufy-redis-cluster-4容器,并连接其 redis 实例 进入交互终端
docker exec -it lufy-redis-cluster-4 redis-cli -c -p 6379

此时输入cluster info可查看集群状态,输出信息如下:

截屏2025-11-04 18.03.44

可以看出关键信息:

  1. cluster_state:ok

集群整体状态正常,无故障。

  1. 槽位状态:
  • cluster_slots_assigned:16384:所有 16384 个槽位都已分配
  • cluster_slots_ok:16384:所有槽位均处于可用状态,无失效槽位
  • cluster_slots_pfail:0:没有槽位处于疑似故障(pfail)或确认故障(fail)状态
  1. 节点数量
  • cluster_known_nodes:6:集群共识别到 6 个节点(与我们部署一致)
  • cluster_size:3:集群中有 3 个主节点
  1. 剩下是通信状态

节点间的 ping/pong 消息收发正常(cluster_stats_messages_* 数值正常增长),说明节点间心跳通信正常

2.主从复制验证

docker exec -it lufy-redis-cluster-4 redis-cli -c -p 6379# 2. 写入3个不同key,观察槽位与节点分配
172.20.1.4:6379> set user:1 zhangsan
-> Redirected to slot [14595] located at 172.20.1.3:6379  # 分配到主节点3(槽14595)
OK172.20.1.3:6379> set order:1001 paid
-> Redirected to slot [9189] located at 172.20.1.2:6379  # 分配到主节点2(槽9189)
OK172.20.1.2:6379> set product:500 iphone
-> Redirected to slot [2891] located at 172.20.1.1:6379  # 分配到主节点1(槽2891)
OK# 3. 验证从节点数据同步(连接主节点1的从节点5)
docker exec -it lufy-redis-cluster-5 redis-cli -c -p 6379
172.20.1.5:6379> get product:500  # 从节点成功读取主节点1的数据
"iphone"

3. AOF 和 RDB 持久化

之前在配置文件中配置了AOF和RDB持久化,其实现代redis默认就是AOF和RDB混合持久化

# 进入容器
(base) xing@xing-2 redis-cluster % docker exec -it lufy-redis-cluster-1 sh
/data # cd appendonlydir/
/data/appendonlydir # ls
# 输出三个持久化文件
appendonly.aof.1.base.rdb  appendonly.aof.1.incr.aof  appendonly.aof.manifest

4. 内存淘汰策略

在配置文件中,定义了内存淘汰策略是 allkeys-lru,也就是说redis内存达到最大值时(配置1GB)会从所有键(不管是否过期) 中,删除 “最近最少使用(LRU)” 的键,释放内存

5. 主从同步

通常有三个场景/阶段:

  1. 初始化阶段:从节点首次连接主节点----全量复制
  • 向主节点发送PSYNC ? -1命令,表明 “首次同步,需要全量数据”
  • 主节点收到请求后,执行BGSAVE后台生成 RDB 文件(不阻塞主节点写操作),同时将生成 RDB 期间的 “增量写命令” 暂存到复制缓冲区
  • 主节点先将 RDB 文件发送给从节点,从节点接收后清空本地数据、加载 RDB 恢复全量数据;
  • RDB 发送完成后,主节点再将复制缓冲区的增量命令发给从节点,从节点执行这些命令,追上主节点数据;--增量复制
  1. 日常阶段:主从数据实时同步
    全量复制完成后,主节点每执行一次写命令(如set/hset),都会通过复制积压缓冲区(环形缓冲区,默认 16MB)实时向从节点发送该命令,从节点接收后立即执行,保证数据与主节点一致。

  2. 异常恢复
    若从节点短暂中断,而且中断期间主节点执行了写命令怎么办呢?
    --偏移量
    主从节点都会维护一个偏移量字段,从节点恢复后会主动向主节点发送自己的偏移量,主节通过偏移量对比即可知道从机的数据是否是最新的,然后判断是否进行增量复制或者全局复制

演示主节点宕机的情况:

# 进入主节点1命令行
docker exec -it lufy-redis-cluster-1 redis-cli -c -p 6379
# 写入一个测试键
172.20.1.1:6379> set test:failover "主节点1写入的数据"
OK

此时将主节点1停机,1对应的从节点为5

docker stop lufy-redis-cluster-1

等待节点5被投票为新的主节点(15s,配置文件中设定):

# 查看集群节点状态,确认从节点5已成为主节点
docker exec -it lufy-redis-cluster-5 redis-cli -c -p 6379 cluster nodes | grep "master"

整个过程:

(base) xing@xing-2 redis-cluster % docker exec -it lufy-redis-cluster-1 redis-cli -c -p 6379
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> set test:failover "主节点1写入的数据"
-> Redirected to slot [15677] located at 172.20.1.3:6379
OK
172.20.1.3:6379> exit
(base) xing@xing-2 redis-cluster % docker exec -it lufy-redis-cluster-5 redis-cli -c -p 6379
127.0.0.1:6379> get test:failover
-> Redirected to slot [15677] located at 172.20.1.3:6379
"\xe4\xb8\xbb\xe8\x8a\x82\xe7\x82\xb91\xe5\x86\x99\xe5\x85\xa5\xe7\x9a\x84\xe6\x95\xb0\xe6\x8d\xae"
172.20.1.3:6379> exit
(base) xing@xing-2 redis-cluster % docker stop lufy-redis-cluster-1
lufy-redis-cluster-1
(base) xing@xing-2 redis-cluster % docker exec -it lufy-redis-cluster-5 redis-cli -c -p 6379 cluster nodes | grep "master"
b8856e22ac1797403f689f1a9799d87e80b9f5d9 172.20.1.5:6379@16379 myself,master - 0 0 7 connected 0-5460
dbb055bbca214e0703d250759f12dae4d6d8aa0e 172.20.1.1:6379@16379 master,fail - 1762260398920 1762260396000 1 connected
44b75abd921a23e05e7c9e800eb63ae667f530c1 172.20.1.2:6379@16379 master - 0 1762261070092 2 connected 5461-10922
58854c91137ae1052934e3cee1fd1b862a75809c 172.20.1.3:6379@16379 master - 0 1762261071139 3 connected 10923-16383
(base) xing@xing-2 redis-cluster % docker exec -it lufy-redis-cluster-5 redis-cli -c -p 6379
127.0.0.1:6379> get test:failover
-> Redirected to slot [15677] located at 172.20.1.3:6379
"\xe4\xb8\xbb\xe8\x8a\x82\xe7\x82\xb91\xe5\x86\x99\xe5\x85\xa5\xe7\x9a\x84\xe6\x95\xb0\xe6\x8d\xae"
172.20.1.3:6379> exit
(base) xing@xing-2 redis-cluster % 

5 节点标记为 主节点,并接管原主节点 1 的槽位(0-5460);同时,原主节点 1 的状态会被标记为 fail

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/956040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025.11.4 - A

今天工程实训和英语,加油

移动通信基站

移动通信基站2G GSM基站学生的尝试使用 *#06# 移动设备标识码详解:SN、MEID、IMEI1、IMEI2SN:产品序列号,用于设备管理(所有设备都有) MEID:CDMA网络设备的唯一识别码(仅CDMA制式设备有) IMEI:GSM/UMTS/LTE网络设…

kaggle提交 名字不是submission.csv的提交方法

1 运行完下载下来再重新上传提交,可以用其它名字(格式对就行) 2 Save Version离线运行完,点击output中的某个csv,点击submit to competition

实用指南:【Nest】登录鉴权

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

程序员修炼之道:从小工到专家-2

读《程序员修炼之道》前半部分,最戳我的不是高深理论,而是满篇的“务实主义”——教你如何在deadline、需求变更、技术债之间,找到最落地的解决方案,而不是追求“完美却无法实现”的理想代码。 书里提到的“原型与…

设计模式--外观模式:简化繁琐环境的统一接口

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

从零实现3D Gaussian Splatting:完整渲染流程的PyTorch代码详解

3D Gaussian Splatting(3DGS)现在几乎成了3D视觉领域的标配技术。NVIDIA把它整合进COSMOS,Meta的新款AR眼镜可以直接在设备端跑3DGS做实时环境捕获和渲染。这技术已经不只是停留在论文阶段了,产品落地速度是相当快…

NOIP2025模拟1

T1:公司的供应链(dag) 思路: 大概就是推出性质但是没写出来。 我们不难发现,对于一个环来说,把环内全部的边删掉是合法的。 然后我们就从一个点开始搜,如果没有环,就把经过的边都标记一下,这是要保留的。然后…

文生视频时代,RustFS如何成为AI资产库的最佳底座?

文生视频时代,RustFS如何成为AI资产库的最佳底座?随着Sora、Pika等文生视频模型引爆2025年AI领域,存储正取代计算成为制约创新的关键瓶颈——处理一段3分钟1080P视频产生的数据量,相当于50万张标准图片的存储需求。…

HTTP 与 SOCKS5 代理协议:企业级选型指南与工程化实践

核心定位与结论 目标读者 企业网络架构、数据平台与安全合规团队 核心结论 协议选型原则:HTTP 代理:优先用于 Web 爬取与 API 调用等应用层流量 SOCKS5 代理:优先用于多协议、TCP/UDP、长连接或非 Web 流量 架构策略…

NOIP2025 游记

11.4 开坑。考完 CSP 像在坐过山车,T3 随时可以挂 40 分,10 号之前睡不好觉。 上午 dmy,打你大坝。 每次考试摸完鱼,只有暴力分,还要给 pyb 编理由真的太难了。 丝之歌拿到了飞针,代价是掉了一千念珠,没关系每关…

用 CodeBuddy CLI + Prompt,从零到可运行:前后端混合管理强大的系统的高效实战

用 CodeBuddy CLI + Prompt,从零到可运行:前后端混合管理强大的系统的高效实战pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

最小二乘问题详解8:Levenberg-Marquardt方法

本文系统讲解了Levenberg-Marquardt方法的原理、算法流程与C++实现,阐明其如何通过自适应阻尼在Gauss-Newton与梯度下降之间智能切换,从而高效稳健地求解非线性最小二乘问题。1 引言 对于非线性最小二乘问题的求解来…

20251104周二日记

20251104周二日记补充一下昨晚和师姐聊天收获:不要一篇篇复现,先总体调研。现在的DIFFGS很好,跑着看看。可以当baseline,从其他文章里找创新点和性能突破点。别怕算力限制,可以training free,而且在算力受限情况…

P16.土堆说卷积(可选看)

P16.土堆说卷积(可选看)16.1torch.nn.functional.conv2d的参数(官网)点击查看代码 input:input tensor of shape (minibatch,in_channels,iH,iW) weight:filters of shape (out_channels,in_channelsgroups,kH,k…

25.11.4联考题解

CF1905F 首先判断特殊情况:\(\forall i,p_i=i\) 答案一定是 \(n-2\)。然后考虑一个位置如果已经满足条件我们先统计到答案中,对于不满足条件的位置,考虑去进行交换的贡献。如果存在一个位置满足 \(p_i=i\) 并且前面…

d11.4t4 answer

d11.4t4 answer 题目 题目描述 小 ∗ 有一条地铁线路。 有 \(n\) 个嘟嘟要乘坐地铁。第 \(i\) 个嘟嘟会在第 \(l_i\)站上车,第 \(r_i\) 站下车。为了方便,我们假定有 \(2n\) 个地铁站,且 \(l_i\) , \(r_i\) 互不相…

详细介绍:当AI化身数据炼金术士:初级Python开发者如何将创意炼成黄金代码?—— 老码农的炼金术指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【学习笔记】kafka权威指南——第3章 kafka生产者—向kafka写入资料

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P15.神经网路的基本骨架——nn.Module的使用

P15.神经网路的基本骨架——nn.Module的使用打开PyTorch官网 1.找到troch.nn的Containers2.打开pycharm:代码-生成-重写方法-选择第一个要初始化的方法__init__3.pycharm运行代码如下点击查看代码 import torch from …