docker-compose配置Sidekiq连接AWS ElastiCache Redis集群问题
核心错误点
你之前的配置思路从根上就错了:
- 把redis容器的
command改成redis-cli -h *.*.use1.cache.amazonaws.com -p 6379完全无效:redis-cli是Redis的交互式客户端工具,不是常驻服务进程,容器启动后执行完该命令会直接退出,必然启动失败。 - 对接AWS ElastiCache Redis根本不需要单独部署本地Redis容器做转发,Rails和Sidekiq本身就可以直接通过Redis协议连接ElastiCache端点,只要网络层打通即可。
前置检查
在改配置之前先确认网络连通性:
- ElastiCache默认部署在AWS私有VPC内,如果你是在本地办公网环境直连,需要先通过VPN打通本地和VPC的网络,或者给ElastiCache开启公网访问(生产环境严禁这么做)。
- 先在运行docker的宿主机上执行
redis-cli -h 你的ElastiCache端点 -p 6379 ping,如果返回PONG再继续后续配置,不通就先查安全组、路由规则。 - 如果你的ElastiCache开启了TLS加密、AUTH认证,提前记好对应的端口、密码参数。
方案1:直连ElastiCache(无本地Redis)
直接删掉compose文件里的本地redis服务定义,把app和worker_sidekiq服务里的REDIS_URL环境变量直接改成ElastiCache的连接地址即可,修改后的完整compose配置如下:
version: "3.3" services: db: image: postgres:12.9-alpine ports: - "5432:5432" volumes: - db_data_postgres:/var/lib/postgresql/data networks: appnet: ipv4_address: 172.20.0.3 app: build: context: . volumes: - .:/app - gem_cache:/usr/local/bundle/gems - node_modules:/app/node_modules depends_on: - db - worker_sidekiq links: - db ports: - "8000:8000" env_file: - .env environment: # 无密码无加密的连接串格式,有密码格式为redis://:你的密码@端点:6379/0 # 开TLS的话把开头改成rediss://,端口换成6380 - REDIS_URL=redis://*.*.use1.cache.amazonaws.com:6379/0 command: bash -c "rm -f tmp/pids/server.pid && RAILS_ENV=development bin/rails s -b '0.0.0.0' -p 8000" networks: appnet: ipv4_address: 172.20.0.5 worker_sidekiq: build: . image: app command: bash -c "bundle exec sidekiq" volumes: - .:/app - gem_cache:/usr/local/bundle/gems - node_modules:/app/node_modules environment: # 和app服务保持完全一致的连接串 - REDIS_URL=redis://*.*.use1.cache.amazonaws.com:6379/0 networks: appnet: ipv4_address: 172.20.0.6 networks: appnet: ipam: config: - subnet: 172.20.0.0/16 volumes: gem_cache: db_data_postgres: node_modules:
配置注意事项:
- 连接串末尾的
/0代表使用Redis的0号数据库,如果你的ElastiCache禁用了数据库选择,直接去掉这部分即可。 - 如果ElastiCache开启了集群模式(Cluster Mode Enabled),默认的Redis客户端不支持集群寻址,需要修改Sidekiq初始化配置,否则会出现MOVED重定向报错。配置示例:
# config/initializers/sidekiq.rb Sidekiq.configure_server do |config| config.redis = { cluster: [ENV['REDIS_URL']] # 有密码的话追加 password: '你的密码' } end Sidekiq.configure_client do |config| config.redis = { cluster: [ENV['REDIS_URL']] } end
方案2:保留本地Redis做开发,按需切换云上连接
如果你平时开发需要用本地Redis,不需要改动现有redis服务的任何启动参数,只需要通过.env文件管理REDIS_URL的值即可:
- 本地开发时
REDIS_URL=redis://redis:6379,走本地容器内的Redis - 需要对接ElastiCache时,把
.env里的REDIS_URL改成对应的ElastiCache连接串,重启app和sidekiq容器即可生效,完全不需要修改redis容器的启动命令。
常见报错排查
- 连接超时:优先检查ElastiCache绑定的安全组,确认放通了docker主机所在网段的6379(非加密)/6380(加密)端口入站规则,再确认VPC路由、VPN连接正常。
- 认证失败:带密码的连接串格式里,密码前面的冒号不能省略,正确格式是
redis://:密码@地址:端口。 - MOVED/ASK重定向报错:说明ElastiCache开了集群模式,按照上面的Sidekiq集群配置修改初始化文件即可。
内容的提问来源于stack exchange,提问作者Serban Marin-Eusebiu
相关产品推荐
相关产品推荐

