K8s上Redis 5.0.9-alpine集群状态异常,redis-py连接失败求助
Redis集群连接失败问题排查与解决
问题背景
- 在Kubernetes上通过StatefulSet部署3个副本的Redis-Server,使用镜像
redis:5.0.9-alpine,已开启cluster mode - 使用官方Redis Python库
redis-py(最新版本及降级至4.1.0)连接集群时触发索引错误 - 因依赖限制无法升级Redis镜像版本
错误信息
File "/code/./app/client/redisclient.py", line 40, in create_redis_cluster_mode rc = Redis(startup_nodes=nodes, **{'password':redis_pwd, 'decode_responses':True}) File "/usr/local/lib/python3.9/site-packages/redis/cluster.py", line 588, in __init__ self.nodes_manager = NodesManager( File "/usr/local/lib/python3.9/site-packages/redis/cluster.py", line 1330, in __init__ self.initialize() File "/usr/local/lib/python3.9/site-packages/redis/cluster.py", line 1632, in initialize self.default_node = self.get_nodes_by_server_type(PRIMARY)[0] IndexError: list index out of range
连接代码
from redis.cluster import RedisCluster as Redis from redis.cluster import ClusterNode def create_redis_cluster(): nodes = [ClusterNode(redis_host, redis_port, server_type= 'primary')] rc = Redis(startup_nodes=nodes, **{'password':redis_pwd, 'decode_responses':True})
Redis集群状态异常
进入所有3个Redis StatefulSet Pod执行cluster info和cluster nodes,结果显示集群未正常组建:
127.0.0.1:6379> cluster info cluster_state:fail cluster_slots_assigned:0 cluster_slots_ok:0 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:1 cluster_size:0 cluster_current_epoch:0 cluster_my_epoch:0 cluster_stats_messages_sent:0 cluster_stats_messages_received:0 127.0.0.1:6379> cluster nodes 7ddd7d8ce5352db7b3d1f168b4c7db94535d6b2e :6379@16379 myself,master - 0 0 0 connected
每个节点仅识别自身,无槽位分配,集群状态为fail,这是连接失败的核心原因。
解决方案步骤
1. 正式初始化Redis集群
Redis集群未完成组建,需要手动执行初始化命令:
- 先获取3个Pod的IP或StatefulSet DNS名称(例如
redis-0.redis-headless.svc.cluster.local) - 进入任意一个Redis Pod,执行集群创建命令:
(若需要主从架构,将redis-cli --cluster create <pod1-ip>:6379 <pod2-ip>:6379 <pod3-ip>:6379 --cluster-replicas 0--cluster-replicas设为1,会自动分配1主2从) - 执行过程中输入
yes确认集群配置
2. 验证集群状态
初始化完成后,在任意Pod内执行:
cluster info:确认cluster_state:ok、cluster_slots_assigned:16384cluster nodes:能看到3个节点的信息,包含主从角色(若配置)
3. 调整Python连接代码
- 移除
server_type='primary'参数,让redis-py自动发现集群节点 - 修改后的代码:
注:from redis.cluster import RedisCluster as Redis from redis.cluster import ClusterNode def create_redis_cluster(): nodes = [ClusterNode(redis_host, redis_port)] rc = Redis(startup_nodes=nodes, password=redis_pwd, decode_responses=True)startup_nodes仅需提供一个可用节点,库会自动遍历发现整个集群的所有节点
4. 检查K8s网络配置
- 确认StatefulSet关联的Headless Service配置正确,允许Redis节点间的6379(业务端口)和16379(集群总线端口)通信
- 检查Pod的网络策略,确保节点之间可以双向访问
内容的提问来源于stack exchange,提问作者Imran
相关产品推荐
相关产品推荐

