Redis 完全指南 / 17 - 容器化部署
容器化部署
17.1 Docker 单实例部署
基础部署
# 最简启动
docker run -d --name redis -p 6379:6379 redis:7.2
# 带配置的启动
docker run -d --name redis \
-p 6379:6379 \
-v /data/redis/data:/data \
-v /data/redis/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 redis-server /usr/local/etc/redis/redis.conf
生产级 Docker 部署
docker run -d --name redis \
--restart always \
-p 6379:6379 \
-v /data/redis/data:/data \
-v /data/redis/redis.conf:/usr/local/etc/redis/redis.conf \
--memory 4g \
--cpus 2 \
--ulimit nofile=65535:65535 \
redis:7.2 redis-server /usr/local/etc/redis/redis.conf \
--requirepass "YourStr0ngP@ssword" \
--appendonly yes \
--maxmemory 3gb \
--maxmemory-policy allkeys-lru
常用 Docker 参数
| 参数 | 说明 |
|---|---|
-d | 后台运行 |
--restart always | 自动重启 |
-v host:container | 挂载卷(数据持久化) |
--memory 4g | 内存限制 |
--cpus 2 | CPU 限制 |
--ulimit nofile=65535:65535 | 文件描述符限制 |
-p host:container | 端口映射 |
--network host | 使用宿主机网络(高性能) |
17.2 Docker Compose 方案
主从复制方案
# docker-compose-replication.yml
version: '3.8'
x-redis-common: &redis-common
image: redis:7.2
restart: always
networks:
- redis-net
sysctls:
net.core.somaxconn: 1024
ulimits:
nofile:
soft: 65535
hard: 65535
services:
redis-master:
<<: *redis-common
container_name: redis-master
ports:
- "6379:6379"
volumes:
- ./master/data:/data
- ./master/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
interval: 10s
timeout: 3s
retries: 3
redis-slave-1:
<<: *redis-common
container_name: redis-slave-1
ports:
- "6380:6379"
volumes:
- ./slave1/data:/data
command: redis-server --replicaof redis-master 6379 --masterauth mypassword --appendonly yes --requirepass mypassword
depends_on:
- redis-master
redis-slave-2:
<<: *redis-common
container_name: redis-slave-2
ports:
- "6381:6379"
volumes:
- ./slave2/data:/data
command: redis-server --replicaof redis-master 6379 --masterauth mypassword --appendonly yes --requirepass mypassword
depends_on:
- redis-master
networks:
redis-net:
driver: bridge
哨兵方案
# docker-compose-sentinel.yml
version: '3.8'
x-redis-common: &redis-common
image: redis:7.2
restart: always
networks:
- redis-net
x-sentinel-common: &sentinel-common
image: redis:7.2
restart: always
networks:
- redis-net
command: redis-sentinel /etc/redis/sentinel.conf
services:
redis-master:
<<: *redis-common
container_name: redis-master
ports:
- "6379:6379"
volumes:
- ./master/data:/data
command: redis-server --requirepass mypassword --appendonly yes
redis-slave-1:
<<: *redis-common
container_name: redis-slave-1
ports:
- "6380:6379"
command: redis-server --replicaof redis-master 6379 --masterauth mypassword --requirepass mypassword --appendonly yes
depends_on:
- redis-master
redis-slave-2:
<<: *redis-common
container_name: redis-slave-2
ports:
- "6381:6379"
command: redis-server --replicaof redis-master 6379 --masterauth mypassword --requirepass mypassword --appendonly yes
depends_on:
- redis-master
sentinel-1:
<<: *sentinel-common
container_name: sentinel-1
ports:
- "26379:26379"
volumes:
- ./sentinel1/sentinel.conf:/etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2
sentinel-2:
<<: *sentinel-common
container_name: sentinel-2
ports:
- "26380:26379"
volumes:
- ./sentinel2/sentinel.conf:/etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2
sentinel-3:
<<: *sentinel-common
container_name: sentinel-3
ports:
- "26381:26379"
volumes:
- ./sentinel3/sentinel.conf:/etc/redis/sentinel.conf
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2
networks:
redis-net:
driver: bridge
哨兵配置文件模板:
# sentinel.conf
port 26379
sentinel monitor mymaster redis-master 6379 2
sentinel auth-pass mymaster mypassword
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
集群方案
# docker-compose-cluster.yml
version: '3.8'
x-redis-node: &redis-node
image: redis:7.2
restart: always
networks:
- redis-cluster
command: >
redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--requirepass mypassword
--masterauth mypassword
services:
redis-node-1:
<<: *redis-node
container_name: redis-node-1
ports:
- "6371:6379"
volumes:
- ./node1/data:/data
redis-node-2:
<<: *redis-node
container_name: redis-node-2
ports:
- "6372:6379"
volumes:
- ./node2/data:/data
redis-node-3:
<<: *redis-node
container_name: redis-node-3
ports:
- "6373:6379"
volumes:
- ./node3/data:/data
redis-node-4:
<<: *redis-node
container_name: redis-node-4
ports:
- "6374:6379"
volumes:
- ./node4/data:/data
redis-node-5:
<<: *redis-node
container_name: redis-node-5
ports:
- "6375:6379"
volumes:
- ./node5/data:/data
redis-node-6:
<<: *redis-node
container_name: redis-node-6
ports:
- "6376:6379"
volumes:
- ./node6/data:/data
networks:
redis-cluster:
driver: bridge
# 创建集群
docker-compose -f docker-compose-cluster.yml up -d
# 等待所有节点启动后
docker exec -it redis-node-1 redis-cli -a mypassword --cluster create \
redis-node-1:6379 redis-node-2:6379 redis-node-3:6379 \
redis-node-4:6379 redis-node-5:6379 redis-node-6:6379 \
--cluster-replicas 1 --cluster-yes
17.3 Kubernetes 部署
使用 Bitnami Helm Chart
# 添加 Helm 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 安装 Redis 主从
helm install redis bitnami/redis \
--set auth.password=mypassword \
--set master.persistence.size=10Gi \
--set replica.replicaCount=2 \
--set replica.persistence.size=10Gi \
--set sentinel.enabled=true \
--namespace redis --create-namespace
# 安装 Redis Cluster
helm install redis-cluster bitnami/redis-cluster \
--set password=mypassword \
--set cluster.nodes=6 \
--set cluster.replicas=1 \
--set persistence.size=10Gi \
--namespace redis --create-namespace
Redis Operator(Spotahome)
# redis-operator-deployment.yml
apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
name: my-redis
namespace: redis
spec:
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 256Mi
redis:
replicas: 3
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
storage:
persistentVolumeClaim:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# 安装 Redis Operator
helm repo add redis-operator https://spotahome.github.io/redis-operator
helm install redis-operator redis-operator/redis-operator
# 部署 Redis Failover
kubectl apply -f redis-operator-deployment.yml
17.4 数据持久化策略
Docker 数据卷
# 使用命名卷
docker volume create redis-data
docker run -d --name redis -v redis-data:/data redis:7.2
# 使用绑定挂载
docker run -d --name redis -v /host/redis/data:/data redis:7.2
# 备份
docker exec redis redis-cli BGSAVE
docker cp redis:/data/dump.rdb ./backup/
# 恢复
docker cp ./backup/dump.rdb redis:/data/
docker restart redis
17.5 网络优化
# docker-compose.yml 优化
services:
redis:
image: redis:7.2
# 使用 host 网络(性能最佳,但牺牲网络隔离)
network_mode: host
# 或使用自定义网络
networks:
redis-net:
ipv4_address: 172.20.0.10
# Linux 内核参数优化
sysctl -w net.core.somaxconn=1024
sysctl -w vm.overcommit_memory=1
echo never > /sys/kernel/mm/transparent_hugepage/enabled
📌 业务场景
场景一:开发环境快速启动
docker-compose up -d
# 30 秒内拥有完整的 Redis 主从+哨兵环境
场景二:CI/CD 测试环境
# GitHub Actions
services:
redis:
image: redis:7.2
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
场景三:K8s 生产环境
# 使用 Helm 部署高可用 Redis Cluster
helm install redis bitnami/redis-cluster \
--set password=$REDIS_PASSWORD \
--set cluster.nodes=6 \
--set persistence.storageClass=fast-ssd