Docker 部署 Redis
概述
Redis 是一个开源的内存数据结构存储系统,可用作数据库、缓存和消息中间件。使用 Docker 部署 Redis 可以简化安装配置、提高部署效率,并确保环境一致性。本文档介绍如何使用 Docker 部署和管理 Redis 服务。
基础部署
1. 使用官方镜像
# 拉取最新版本的 Redis 镜像
docker pull redis:latest
# 运行基础 Redis 容器
docker run -d \
--name redis-server \
-p 6379:6379 \
redis:latest
2. 自定义配置部署
创建自定义的 Redis 配置文件:
# redis.conf
# 网络配置
bind 0.0.0.0
port 6379
timeout 0
tcp-keepalive 300
# 通用配置
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
# 快照配置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
# 复制配置
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-ping-replica-period 10
repl-timeout 60
repl-disable-tcp-nodelay no
repl-backlog-size 1mb
repl-backlog-ttl 3600
# 安全配置
# requirepass your_password
maxclients 10000
# 内存管理
maxmemory 256mb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# 延迟监控
latency-monitor-threshold 0
# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# 事件通知
notify-keyspace-events ""
# 高级配置
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
使用自定义配置运行容器:
# 创建配置目录
mkdir -p redis/conf
mkdir -p redis/data
mkdir -p redis/logs
# 复制配置文件
cp redis.conf redis/conf/
# 运行容器
docker run -d \
--name redis-custom \
-p 6379:6379 \
-v $(pwd)/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro \
-v $(pwd)/redis/data:/data \
-v $(pwd)/redis/logs:/var/log/redis \
redis:latest redis-server /usr/local/etc/redis/redis.conf
Docker Compose 部署
基础配置
# docker-compose.yml
version: "3.8"
services:
redis:
image: redis:7-alpine
container_name: redis-server
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- ./redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./redis/data:/data
- ./redis/logs:/var/log/redis
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- cache
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
networks:
cache:
driver: bridge
volumes:
redis_data:
生产环境配置
# docker-compose.prod.yml
version: "3.8"
services:
redis:
image: redis:7-alpine
container_name: redis-prod
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
- ./redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./redis/logs:/var/log/redis
- ./redis/backup:/backup
command: >
redis-server /usr/local/etc/redis/redis.conf
--requirepass ${REDIS_PASSWORD}
--maxmemory 1gb
--maxmemory-policy allkeys-lru
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
networks:
- cache
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 30s
timeout: 10s
retries: 3
ulimits:
nofile:
soft: 65536
hard: 65536
redis-backup:
image: redis:7-alpine
container_name: redis-backup
restart: "no"
volumes:
- ./redis/backup:/backup
- redis_data:/data:ro
command: >
sh -c "
redis-cli -a ${REDIS_PASSWORD} BGSAVE &&
sleep 10 &&
cp /data/dump.rdb /backup/backup_$$(date +%Y%m%d_%H%M%S).rdb
"
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
networks:
- cache
networks:
cache:
driver: bridge
volumes:
redis_data:
driver: local
Redis 集群配置
# docker-compose-cluster.yml
version: "3.8"
services:
redis-node-1:
image: redis:7-alpine
container_name: redis-node-1
restart: unless-stopped
ports:
- "7001:6379"
volumes:
- ./redis/cluster/node-1/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./redis/cluster/node-1/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster
redis-node-2:
image: redis:7-alpine
container_name: redis-node-2
restart: unless-stopped
ports:
- "7002:6379"
volumes:
- ./redis/cluster/node-2/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./redis/cluster/node-2/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster
redis-node-3:
image: redis:7-alpine
container_name: redis-node-3
restart: unless-stopped
ports:
- "7003:6379"
volumes:
- ./redis/cluster/node-3/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./redis/cluster/node-3/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster
redis-cluster-init:
image: redis:7-alpine
container_name: redis-cluster-init
restart: "no"
depends_on:
- redis-node-1
- redis-node-2
- redis-node-3
command: >
sh -c "
echo 'yes' | redis-cli --cluster create
redis-node-1:6379 redis-node-2:6379 redis-node-3:6379
--cluster-replicas 0
"
networks:
- redis-cluster
networks:
redis-cluster:
driver: bridge
配置说明
重要配置参数
| 参数 | 说明 | 推荐值 |
|---|---|---|
maxmemory | 最大内存使用量 | 根据服务器内存调整 |
maxmemory-policy | 内存满时的淘汰策略 | allkeys-lru |
save | RDB 持久化配置 | 900 1 300 10 60 10000 |
appendonly | 是否启用 AOF | yes |
appendfsync | AOF 同步策略 | everysec |
timeout | 客户端超时时间 | 0 (禁用) |
tcp-keepalive | TCP keepalive | 300 |
内存淘汰策略
noeviction: 不淘汰,写入时报错allkeys-lru: 从所有 key 中使用 LRU 算法淘汰volatile-lru: 从设置了过期时间的 key 中使用 LRU 算法淘汰allkeys-random: 从所有 key 中随机淘汰volatile-random: 从设置了过期时间的 key 中随机淘汰volatile-ttl: 淘汰最近要过期的 key
监控和维护
1. 基础监控命令
# 连接 Redis
docker exec -it redis-server redis-cli
# 查看服务器信息
INFO server
# 查看内存使用情况
INFO memory
# 查看客户端连接
INFO clients
# 查看慢查询
SLOWLOG get 10
# 查看键空间统计
INFO keyspace
2. 性能监控脚本
#!/bin/bash
# redis-monitor.sh
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""
# 获取内存使用情况
get_memory_usage() {
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info memory | grep used_memory_human
}
# 获取连接数
get_connected_clients() {
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info clients | grep connected_clients
}
# 获取命中率
get_hit_rate() {
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep keyspace_hits
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep keyspace_misses
}
echo "=== Redis 监控信息 ==="
echo "时间: $(date)"
echo "内存使用: $(get_memory_usage)"
echo "连接数: $(get_connected_clients)"
echo "命中率统计:"
get_hit_rate
3. 备份和恢复
# 手动备份
docker exec redis-server redis-cli BGSAVE
# 复制备份文件
docker cp redis-server:/data/dump.rdb ./backup/
# 恢复数据
docker cp ./backup/dump.rdb redis-server:/data/
docker restart redis-server
4. 日志分析
# 查看 Redis 日志
docker logs redis-server
# 实时监控日志
docker logs -f redis-server
# 分析慢查询
docker exec redis-server redis-cli SLOWLOG get 10
安全配置
1. 密码认证
# redis.conf
requirepass your_strong_password
2. 网络安全
# redis.conf
# 只允许本地连接
bind 127.0.0.1
# 禁用危险命令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command SHUTDOWN ""
3. 防火墙配置
# 只允许特定 IP 访问
iptables -A INPUT -p tcp --dport 6379 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
故障排除
常见问题
内存不足
# 检查内存使用 docker exec redis-server redis-cli info memory # 清理过期键 docker exec redis-server redis-cli FLUSHDB连接数过多
# 查看连接详情 docker exec redis-server redis-cli CLIENT LIST # 关闭空闲连接 docker exec redis-server redis-cli CLIENT KILL TYPE normal持久化失败
# 检查磁盘空间 df -h # 检查 Redis 日志 docker logs redis-server | grep -i error
性能优化建议
内存优化
- 合理设置
maxmemory和maxmemory-policy - 使用合适的数据结构
- 及时清理过期数据
- 合理设置
网络优化
- 使用连接池
- 批量操作减少网络往返
- 启用 pipeline
持久化优化
- 根据业务需求选择 RDB 或 AOF
- 合理设置保存频率
- 使用 SSD 存储
最佳实践
生产环境建议
- 使用 Redis 6.0+ 版本
- 启用密码认证
- 配置适当的最大内存
- 启用持久化
- 设置健康检查
监控建议
- 监控内存使用率
- 监控连接数
- 监控命中率
- 设置告警机制
备份策略
- 定期自动备份
- 异地备份
- 测试恢复流程
- 保留多个备份版本
安全建议
- 使用强密码
- 限制网络访问
- 禁用危险命令
- 定期更新版本
