Redis集群部署方案
在一台云服务器上部署Redis集群,让云服务器上的Java程序和你本地电脑的Java程序都能访问。以下是完整的解决方案:
1. Docker Compose 配置文件
# docker-compose-redis-cloud.yml
version: '3.8'
services:
redis-node-1:
image: redis:7.2-alpine
container_name: redis-node-1
restart: always
ports:
- "7001:7001" # Redis服务端口
- "17001:17001" # 集群总线端口
volumes:
- ./data/redis-7001:/data
- ./conf/redis-7001.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 只保留网络名称,去掉IP
healthcheck:
test: ["CMD", "redis-cli", "-p", "7001", "ping"]
interval: 30s
timeout: 10s
retries: 3
redis-node-2:
image: redis:7.2-alpine
container_name: redis-node-2
restart: always
ports:
- "7002:7002"
- "17002:17002"
volumes:
- ./data/redis-7002:/data
- ./conf/redis-7002.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 只保留网络名称,去掉IP
healthcheck:
test: ["CMD", "redis-cli", "-p", "7002", "ping"]
interval: 30s
timeout: 10s
retries: 3
redis-node-3:
image: redis:7.2-alpine
container_name: redis-node-3
restart: always
ports:
- "7003:7003"
- "17003:17003"
volumes:
- ./data/redis-7003:/data
- ./conf/redis-7003.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 只保留网络名称,去掉IP
healthcheck:
test: ["CMD", "redis-cli", "-p", "7003", "ping"]
interval: 30s
timeout: 10s
retries: 3
redis-node-4:
image: redis:7.2-alpine
container_name: redis-node-4
restart: always
ports:
- "7004:7004"
- "17004:17004"
volumes:
- ./data/redis-7004:/data
- ./conf/redis-7004.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 只保留网络名称,去掉IP
healthcheck:
test: ["CMD", "redis-cli", "-p", "7004", "ping"]
interval: 30s
timeout: 10s
retries: 3
redis-node-5:
image: redis:7.2-alpine
container_name: redis-node-5
restart: always
ports:
- "7005:7005"
- "17005:17005"
volumes:
- ./data/redis-7005:/data
- ./conf/redis-7005.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 只保留网络名称,去掉IP
healthcheck:
test: ["CMD", "redis-cli", "-p", "7005", "ping"]
interval: 30s
timeout: 10s
retries: 3
redis-node-6:
image: redis:7.2-alpine
container_name: redis-node-6
restart: always
ports:
- "7006:7006"
- "17006:17006"
volumes:
- ./data/redis-7006:/data
- ./conf/redis-7006.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-network # 加入同一个网络
healthcheck:
test: ["CMD", "redis-cli", "-p", "7006", "ping"]
interval: 30s
timeout: 10s
retries: 3
networks:
redis-cluster-network: # 网络定义保持不变
driver: bridge
# 删除 ipam 配置,让Docker自动管理IP
2. 一键部署脚本(在云服务器上执行)
#!/bin/bash
# deploy-redis-cloud-fixed.sh
set -e
echo "🚀 开始部署云服务器Redis集群..."
# 1. 获取公网IP(仅用于客户端访问)
echo "📡 获取服务器IP地址..."
PUBLIC_IP=$(curl -s --max-time 5 ifconfig.me || curl -s --max-time 5 ipinfo.io/ip)
if [ -z "$PUBLIC_IP" ]; then
PUBLIC_IP=$(hostname -I | awk '{print $1}')
[ -z "$PUBLIC_IP" ] && PUBLIC_IP="127.0.0.1"
fi
echo "✅ 公网IP: $PUBLIC_IP(用于客户端访问)"
echo "✅ 集群内部将使用容器网络通信"
read -p "按回车继续..."
# 2. 创建目录
mkdir -p {conf,data,scripts}
for port in {7001..7006}; do mkdir -p data/redis-${port}; done
# 3. 生成Redis配置文件(重要:集群通信用容器网络,客户端重定向用公网IP)
for port in 7001 7002 7003 7004 7005 7006; do
cat > conf/redis-${port}.conf << EOF
port ${port}
bind 0.0.0.0
protected-mode no
daemonize no
requirepass "RedisCloud@2024"
masterauth "RedisCloud@2024"
appendonly yes
appendfsync everysec
dir /data
dbfilename dump-${port}.rdb
# 集群配置
cluster-enabled yes
cluster-config-file nodes-${port}.conf
cluster-node-timeout 15000
cluster-require-full-coverage yes
# 重要!告诉客户端重定向到公网IP
# 这样外部客户端收到MOVED响应时知道连接哪里
cluster-announce-ip ${PUBLIC_IP}
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
# 性能配置
maxmemory 2gb
maxmemory-policy allkeys-lru
maxclients 10000
loglevel notice
logfile "/data/redis-${port}.log"
EOF
echo "✅ 生成: conf/redis-${port}.conf"
done
# 4. 设置权限
chmod -R 777 data/
# 5. 检查防火墙
echo "================================================"
echo "请确保安全组开放端口:7001-7006 和 17001-17006"
echo "================================================"
read -p "确认端口已开放?按回车继续..."
# 6. 启动容器
echo "🐳 启动Docker容器..."
docker-compose -f docker-compose-redis-cloud.yml down 2>/dev/null || true
docker-compose -f docker-compose-redis-cloud.yml up -d
# 7. 等待启动
echo "⏳ 等待容器启动..."
sleep 15 # 等待健康检查通过
# 8. 创建集群(使用容器内部网络)
echo "🔗 创建Redis集群..."
docker exec redis-node-1 redis-cli -a "RedisCloud@2024" --cluster create \
redis-node-1:7001 redis-node-2:7002 redis-node-3:7003 \
redis-node-4:7004 redis-node-5:7005 redis-node-6:7006 \
--cluster-replicas 1 --cluster-yes
echo "✅ Redis集群创建完成!"
# 9. 验证集群
echo "📊 验证集群状态..."
sleep 5
cat > scripts/check-cluster.sh << 'CHECK_EOF'
#!/bin/bash
echo "1. 集群节点信息:"
docker exec redis-node-1 redis-cli -a "RedisCloud@2024" -p 7001 cluster nodes
echo -e "\n2. 集群状态:"
docker exec redis-node-1 redis-cli -a "RedisCloud@2024" -p 7001 cluster info | grep -E "(cluster_state|cluster_slots_assigned|cluster_known_nodes)"
echo -e "\n3. 测试数据操作:"
timestamp=$(date +%s)
docker exec redis-node-1 redis-cli -a "RedisCloud@2024" -p 7001 -c set "test:$timestamp" "部署成功"
docker exec redis-node-2 redis-cli -a "RedisCloud@2024" -p 7002 -c get "test:$timestamp"
echo -e "\n4. 内部网络检查:"
docker exec redis-node-1 redis-cli -a "RedisCloud@2024" --cluster check redis-node-1:7001
CHECK_EOF
chmod +x scripts/check-cluster.sh
./scripts/check-cluster.sh
# 10. 生成连接信息(修正管理命令)
cat > connection-info.txt << INFO_EOF
===============================================
✅ Redis集群部署成功!
===============================================
📌 服务器信息:
公网IP: ${PUBLIC_IP} (客户端使用)
Redis密码: RedisCloud@2024
🔌 连接方式:
1. 外部客户端连接:
redis-cli -c -a RedisCloud@2024 -h ${PUBLIC_IP} -p 7001
2. 服务器内部连接:
redis-cli -c -a RedisCloud@2024 -h 127.0.0.1 -p 7001
3. 容器内部连接:
docker exec redis-node-1 redis-cli -a RedisCloud@2024 -p 7001
🛠️ 管理命令:
# 检查集群状态(在服务器上执行)
docker exec redis-node-1 redis-cli -a RedisCloud@2024 --cluster check redis-node-1:7001
# 或
docker exec redis-node-1 redis-cli -a RedisCloud@2024 --cluster check 127.0.0.1:7001
# 查看集群节点
docker exec redis-node-1 redis-cli -a RedisCloud@2024 -p 7001 cluster nodes
# 备份数据
docker exec redis-node-1 redis-cli -a RedisCloud@2024 bgsave
⚠️ 安全提醒:
1. 立即修改默认密码!
2. 安全组只允许必要IP访问
3. 定期监控日志: tail -f data/redis-7001/redis-7001.log
===============================================
INFO_EOF
echo ""
echo "✨ 部署完成!"
echo "📋 连接信息: connection-info.txt"
echo ""
echo "🔍 快速测试:"
echo "1. 服务器内部测试: redis-cli -c -a RedisCloud@2024 -h 127.0.0.1 -p 7001"
echo "2. 本地电脑测试: redis-cli -c -a RedisCloud@2024 -h ${PUBLIC_IP} -p 7001"
3. 本地电脑测试脚本
在你本地电脑上创建测试脚本:
#!/bin/bash
# test-local-connection.sh
# 请修改为你的云服务器公网IP
SERVER_IP="你的云服务器公网IP"
PASSWORD="RedisCloud@2024"
echo "测试从本地连接到云服务器Redis集群..."
# 测试连接
echo "1. 测试连接到节点1:"
redis-cli -c -a ${PASSWORD} -h ${SERVER_IP} -p 7001 ping
echo -e "\n2. 测试写入数据:"
redis-cli -c -a ${PASSWORD} -h ${SERVER_IP} -p 7001 set "local_test_$(date +%s)" "from_local_machine"
echo -e "\n3. 测试读取数据:"
redis-cli -c -a ${PASSWORD} -h ${SERVER_IP} -p 7002 keys "local_test*"
echo -e "\n4. 测试集群信息:"
redis-cli -c -a ${PASSWORD} -h ${SERVER_IP} -p 7003 cluster info | head -10
4. 管理脚本(在云服务器上)
#!/bin/bash
# manage-redis-cluster.sh
SERVER_IP=$(curl -s ifconfig.me || hostname -I | awk '{print $1}')
PASSWORD="RedisCloud@2024"
case "$1" in
status)
echo "容器状态:"
docker-compose -f docker-compose-redis-cloud.yml ps
echo -e "\n集群状态:"
docker exec redis-node-1 redis-cli -a ${PASSWORD} -p 7001 cluster info | grep cluster_state
;;
check)
echo "检查集群健康状态..."
docker exec redis-node-1 redis-cli -a ${PASSWORD} --cluster check ${SERVER_IP}:7001
;;
nodes)
echo "集群节点信息:"
docker exec redis-node-1 redis-cli -a ${PASSWORD} -p 7001 cluster nodes
;;
restart)
echo "重启集群..."
docker-compose -f docker-compose-redis-cloud.yml restart
sleep 5
docker exec redis-node-1 redis-cli -a ${PASSWORD} -p 7001 cluster info | grep cluster_state
;;
stop)
echo "停止集群..."
docker-compose -f docker-compose-redis-cloud.yml down
;;
start)
echo "启动集群..."
docker-compose -f docker-compose-redis-cloud.yml up -d
;;
logs)
docker-compose -f docker-compose-redis-cloud.yml logs -f --tail=50 ${2:-redis-node-1}
;;
backup)
BACKUP_DIR="backup/redis-$(date +%Y%m%d-%H%M%S)"
mkdir -p ${BACKUP_DIR}
echo "备份数据到 ${BACKUP_DIR}..."
for port in 7001 7002 7003 7004 7005 7006; do
docker exec redis-node-${port: -1} redis-cli -a ${PASSWORD} save
docker cp redis-node-${port: -1}:/data ${BACKUP_DIR}/redis-${port}
echo "✅ redis-${port} 备份完成"
done
;;
monitor)
echo "监控集群实时状态 (Ctrl+C 退出)..."
watch -n 2 "docker exec redis-node-1 redis-cli -a ${PASSWORD} -p 7001 cluster info | grep -E '(cluster_state|cluster_slots_assigned|cluster_size)'"
;;
*)
echo "用法: $0 [command]"
echo "命令:"
echo " status 查看状态"
echo " check 检查集群"
echo " nodes 查看节点"
echo " restart 重启集群"
echo " stop 停止集群"
echo " start 启动集群"
echo " logs 查看日志"
echo " backup 备份数据"
echo " monitor 实时监控"
;;
esac
5. 部署步骤
在云服务器上执行:
# 1. 上传文件到云服务器
# docker-compose-redis-cloud.yml
# deploy-redis-cloud.sh
# 2. 给脚本执行权限
chmod +x deploy-redis-cloud.sh
# 3. 执行部署脚本
./deploy-redis-cloud.sh
# 4. 查看部署结果
cat connection-info.txt
在你本地电脑上执行:
# 1. 确保本地已安装redis-cli
# macOS: brew install redis
# Ubuntu: sudo apt install redis-tools
# 2. 修改测试脚本中的IP地址
# 编辑 test-local-connection.sh,将SERVER_IP改为你的云服务器IP
# 3. 测试连接
chmod +x test-local-connection.sh
./test-local-connection.sh
6. Spring Boot 配置示例
# application.yml (云服务器上的Java程序)
spring:
redis:
cluster:
nodes:
- 127.0.0.1:7001
- 127.0.0.1:7002
- 127.0.0.1:7003
- 127.0.0.1:7004
- 127.0.0.1:7005
- 127.0.0.1:7006
max-redirects: 3
password: RedisCloud@2024
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
# application.yml (你本地电脑的Java程序)
spring:
redis:
cluster:
nodes:
- 你的云服务器IP:7001
- 你的云服务器IP:7002
- 你的云服务器IP:7003
- 你的云服务器IP:7004
- 你的云服务器IP:7005
- 你的云服务器IP:7006
max-redirects: 3
password: RedisCloud@2024
timeout: 10000ms # 本地连接需要更长的超时时间
关键注意事项
- 安全组/防火墙:必须开放7001-7006和17001-17006端口
- 密码安全:生产环境请修改默认密码
- 网络延迟:本地连接云服务器会有网络延迟,适当调整超时时间
- 备份策略:定期备份数据
- 监控:建议配置Redis监控
这个配置专门针对你的场景优化,确保云服务器内外部都能正常访问Redis集群。