Python连接Redis Cluster容器受阻,脚本无响应问题求助
连接Docker部署的Redis Cluster时Python脚本卡住无响应
尝试连接Redis Cluster容器失败,执行Python脚本时会卡住且无任何输出。
Python脚本如下:
import redis r = redis.RedisCluster( host='127.0.0.1', port=36379 ) r.set('foo', 'bar') value = r.get('foo') print(value)
Docker Compose配置:
version : '3.4' services: redis: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' ports: - 36379:6379 redis-node-1: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-2: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-3: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-4: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-5: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_REPLICAS=1' - 'REDIS_CLUSTER_CREATOR=yes' depends_on: - redis - redis-node-1 - redis-node-2 - redis-node-3 - redis-node-4
已尝试redis-py-cluster、redis等多个客户端库,结果一致,请问原因是什么?
解决方案
问题原因
Bitnami Redis Cluster容器默认使用容器内部的hostname(如redis、redis-node-1)作为集群节点的通告地址。当Python客户端连接到暴露的36379端口后,集群会返回这些内部hostname给客户端,但本地机器无法解析这些容器hostname,导致客户端尝试连接不存在的地址,最终卡住无响应。
解决步骤
1. 修改Docker Compose,暴露所有节点端口并配置通告IP
给每个Redis节点添加端口映射,并设置REDIS_CLUSTER_ADVERTISED_IP为宿主机IP(或127.0.0.1),让集群向客户端返回可访问的地址:
version : '3.4' services: redis: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36379:6379 redis-node-1: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36380:6379 redis-node-2: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36381:6379 redis-node-3: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36382:6379 redis-node-4: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36383:6379 redis-node-5: image: docker.io/bitnami/redis-cluster:7.0 environment: - 'ALLOW_EMPTY_PASSWORD=yes' - 'REDIS_NODES=redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_REPLICAS=1' - 'REDIS_CLUSTER_CREATOR=yes' - 'REDIS_CLUSTER_ADVERTISED_IP=127.0.0.1' ports: - 36384:6379 depends_on: - redis - redis-node-1 - redis-node-2 - redis-node-3 - redis-node-4
2. 调整Python脚本参数
添加skip_full_coverage_check=True跳过全集群覆盖检查(避免集群初始化时节点未完全就绪导致的异常),同时开启decode_responses=True方便直接读取字符串结果:
import redis r = redis.RedisCluster( host='127.0.0.1', port=36379, skip_full_coverage_check=True, decode_responses=True ) r.set('foo', 'bar') value = r.get('foo') print(value)
3. 可选:本地hosts映射
如果不想修改Docker Compose的通告IP,可以在本地hosts文件(Windows为C:\Windows\System32\drivers\etc\hosts,Linux/macOS为/etc/hosts)中添加以下内容,让本地能解析容器hostname:
127.0.0.1 redis redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
之后重启Python脚本即可。
内容的提问来源于stack exchange,提问作者gumelar
相关产品推荐
相关产品推荐

