硬核实践:使用 Docker 部署生产级 Redis(持久化 + 安全配置 + 高可用)

Redis 容器化部署看起来简单,docker run redis 一条命令就能跑起来。但真到生产环境,问题全来了:数据丢了怎么办?被人扫端口挖矿了怎么防?内存爆了怎么处理?怎么做主从和哨兵?
这篇文章从最基础的 docker run 开始,一路讲到 Docker Compose、持久化策略、安全加固、主从复制、哨兵高可用,把生产环境用 Docker 部署 Redis 的整条链路讲透。
你能从这篇文章得到什么:

  • 三种部署方式的完整命令,复制就能用

  • RDB + AOF 持久化配置,数据不丢

  • 生产级安全加固方案,防挖矿防入侵

  • 主从复制 + 哨兵模式高可用部署

  • 常用运维命令 + 常见问题排查清单
    适合谁看:

  • 想把 Redis 跑起来的 Docker 新手

  • 一直在裸机装 Redis,想容器化迁移的运维

  • 会基础用法,但想搞清楚生产环境最佳实践的开发者

不废话,直接上干货。

一、环境准备

1.1 系统要求

bash 复制代码
# 检查 Docker 版本
docker --version
# Docker version 24.0.7, build afdd53b

# 检查 Docker Compose 版本
docker compose version
# Docker Compose version v2.21.0

1.2 前置检查

bash 复制代码
# 确认 6379 端口未被占用
netstat -tlnp | grep 6379
# 或
ss -tlnp | grep 6379

# 确认宿主机内存足够(Redis 是内存数据库)
free -h

注意:Redis 持久化时 fork 子进程需要额外内存,建议预留至少 50% 内存余量。


二、方式一:docker run 快速启动(适合测试)

2.1 拉取官方镜像

bash 复制代码
# 拉取最新稳定版
docker pull redis:latest

# 推荐:指定明确版本
docker pull redis:7.2-alpine

# 查看本地镜像
docker images | grep redis

选型建议

  • redis:alpine --- 体积小(~30MB),推荐生产使用
  • redis:latest --- 基于 Debian,体积大(~130MB),调试工具全
  • redis:7.2 --- 指定大版本,生产环境锁定版本

2.2 最简启动

bash 复制代码
docker run -d \
  --name redis \
  -p 6379:6379 \
  --restart=always \
  redis:7.2-alpine

2.3 带密码启动

bash 复制代码
docker run -d \
  --name redis \
  -p 6379:6379 \
  --restart=always \
  redis:7.2-alpine \
  redis-server --requirepass "your_strong_password"

2.4 验证连接

bash 复制代码
# 进入容器用 redis-cli 测试
docker exec -it redis redis-cli

# 带密码的情况
docker exec -it redis redis-cli -a "your_strong_password"
# 或进入后认证
127.0.0.1:6379> AUTH your_strong_password
OK

# 测试读写
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"

三、方式二:配置外置 + 数据卷持久化(生产标准)

最简启动只能用默认配置,数据存在容器里,删容器就没了。生产环境必须配置外置 + 数据持久化。

3.1 目录结构规划

bash 复制代码
# 创建 Redis 相关目录
mkdir -p /data/redis/{conf,data,logs}

表格

目录 用途
/data/redis/conf 配置文件 redis.conf
/data/redis/data 持久化数据(RDB + AOF)
/data/redis/logs 日志文件

3.2 配置文件 redis.conf

创建 /data/redis/conf/redis.conf

bash 复制代码
# ========== 基础配置 ==========
# 绑定地址,0.0.0.0 表示允许所有 IP 访问(生产环境建议绑定内网 IP)
bind 0.0.0.0

# 端口
port 6379

# 密码(生产环境必须设置强密码)
requirepass your_strong_password_here

# 数据库数量
databases 16

# 客户端连接数上限
maxclients 10000

# ========== 内存配置 ==========
# 最大内存(根据服务器实际情况设置,示例 2GB)
maxmemory 2gb

# 内存淘汰策略
# allkeys-lru:所有键中优先删除最近最少使用的
# allkeys-lfu:所有键中优先删除使用频率最低的
# volatile-lru:设置了过期时间的键中优先删除最近最少使用的
# noeviction:不淘汰,写满直接报错
maxmemory-policy allkeys-lru

# ========== 持久化 - RDB ==========
# 开启 RDB 持久化
save 900 1      # 900 秒内至少 1 个 key 变更
save 300 10     # 300 秒内至少 10 个 key 变更
save 60 10000   # 60 秒内至少 10000 个 key 变更

# RDB 文件名
dbfilename dump.rdb

# 数据目录
dir /data

# RDB 压缩
rdbcompression yes

# ========== 持久化 - AOF ==========
# 开启 AOF 持久化(推荐生产开启,RDB+AOF 混合模式)
appendonly yes

# AOF 文件名
appendfilename "appendonly.aof"

# AOF 刷盘策略
# always:每次写操作都刷盘(最安全,性能最差)
# everysec:每秒刷盘(推荐,平衡安全和性能)
# no:由操作系统决定刷盘时机(最快,最不安全)
appendfsync everysec

# AOF 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# ========== 日志配置 ==========
# 日志级别:debug、verbose、notice、warning
loglevel notice

# 日志文件
logfile "/data/redis.log"

# ========== 慢查询 ==========
# 慢查询阈值(微秒)
slowlog-log-slower-than 10000

# 慢查询最大记录数
slowlog-max-len 128

# ========== 安全加固 ==========
# 重命名危险命令(生产环境强烈建议)
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG "CONFIG_mysecret"
rename-command SHUTDOWN "SHUTDOWN_mysecret"

# 禁用危险命令(直接置空表示禁用)
# rename-command DEBUG ""

# ========== 其他 ==========
# 后台运行(Docker 部署不要开,否则容器会退出)
# daemonize no

# PID 文件
pidfile /var/run/redis.pid

重要 :Docker 部署 Redis 时,daemonize 必须设为 no(默认就是 no),否则容器启动后立即退出。

3.3 启动容器

bash 复制代码
docker run -d \
  --name redis \
  -p 6379:6379 \
  --restart=always \
  -v /data/redis/conf/redis.conf:/etc/redis/redis.conf:ro \
  -v /data/redis/data:/data \
  -v /data/redis/logs:/var/log/redis \
  --sysctl net.core.somaxconn=1024 \
  redis:7.2-alpine \
  redis-server /etc/redis/redis.conf

参数详解:

表格

参数 作用
-d 后台运行
--name redis 容器命名
-p 6379:6379 端口映射
--restart=always Docker 重启后自动启动
-v .../redis.conf:ro 配置文件只读挂载
-v .../data:/data 数据目录挂载,持久化数据存在这里
--sysctl net.core.somaxconn=1024 调大 TCP 连接队列,解决 Redis 启动警告
redis-server /etc/redis/redis.conf 指定配置文件启动

3.4 验证持久化

bash 复制代码
# 写入测试数据
docker exec -it redis redis-cli -a "your_password"
127.0.0.1:6379> set test_key test_value
OK
127.0.0.1:6379> save   # 手动触发 RDB 持久化
OK
127.0.0.1:6379> exit

# 查看数据文件
ls -la /data/redis/data/
# 应该能看到 dump.rdb 和 appendonly.aof 文件

# 重启容器验证数据不丢
docker restart redis
docker exec -it redis redis-cli -a "your_password" get test_key
# "test_value" --- 数据还在就说明持久化生效了

四、方式三:Docker Compose 部署(推荐)

生产环境统一用 Compose 管理,方便维护和迁移。

4.1 docker-compose.yml

bash 复制代码
version: '3.8'

services:
  redis:
    image: redis:7.2-alpine
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./conf/redis.conf:/etc/redis/redis.conf:ro
      - ./data:/data
      - ./logs:/var/log/redis
    command: redis-server /etc/redis/redis.conf
    sysctls:
      - net.core.somaxconn=1024
      - net.ipv4.tcp_max_syn_backlog=8192
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        hard: 65535
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 5s
    networks:
      - redis-network

networks:
  redis-network:
    driver: bridge

4.2 启动

bash 复制代码
# 前台启动看日志
docker compose up

# 后台启动
docker compose up -d

# 查看状态
docker compose ps

# 查看日志
docker compose logs -f redis

五、持久化策略详解

Redis 有两种持久化方式:RDB 和 AOF,生产环境建议都开(混合模式)。

5.1 RDB 快照

原理:每隔一段时间把内存中的数据全量快照写入磁盘。

优点

  • 文件紧凑,适合备份和灾备
  • 恢复速度快,直接加载 RDB 文件
  • 对性能影响小,fork 子进程写,主进程继续服务

缺点

  • 间隔时间内宕机会丢数据
  • 数据量大时 fork 耗时,可能造成短暂卡顿

配置

bash 复制代码
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data

5.2 AOF 追加文件

原理:把每一条写命令追加到文件末尾,类似 MySQL 的 binlog。

优点

  • 数据安全性高,最多丢 1 秒数据
  • 文件是文本格式,可读可手动修复

缺点

  • 文件体积比 RDB 大
  • 恢复速度比 RDB 慢
  • 写操作频繁时对性能有一定影响

配置

bash 复制代码
appendonly yes
appendfsync everysec   # 每秒刷盘,推荐
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

5.3 混合持久化(Redis 4.0+)

Redis 4.0 之后支持 RDB + AOF 混合模式,AOF 重写时把 RDB 内容写在 AOF 文件开头,后续增量写命令追加。兼顾了 RDB 的恢复速度和 AOF 的数据安全性。

bash 复制代码
# 开启混合持久化(Redis 5.0+ 默认开启)
aof-use-rdb-preamble yes

生产建议:RDB + AOF 混合模式,数据安全性和恢复速度兼顾。


六、安全配置(生产环境必做)

Redis 是被挖矿攻击的重灾区,裸奔的 Redis 公网暴露分分钟被入侵。以下安全措施必须做。

6.1 设置强密码

bash 复制代码
requirepass YourStrongPassword!@#2024

密码要够长够复杂,别用 123456redis 这种弱密码。

6.2 绑定内网 IP

如果只在内网使用,不要绑定 0.0.0.0

bash 复制代码
# 只允许内网访问
bind 192.168.1.100

或者干脆不映射端口,只通过 Docker 内部网络访问:

bash 复制代码
# docker-compose.yml 去掉 ports 配置,只暴露给内部网络
# ports:
#   - "6379:6379"

6.3 重命名 / 禁用危险命令

bash 复制代码
# 直接禁用
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command DEBUG ""

# 重命名,只有知道别名的人能用
rename-command CONFIG "CONFIG_yoursecret"
rename-command SHUTDOWN "SHUTDOWN_yoursecret"
rename-command SAVE "SAVE_yoursecret"

6.4 防火墙限制

bash 复制代码
# 只允许特定 IP 访问 6379
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

6.5 不要用 root 运行容器

bash 复制代码
# docker-compose.yml 中指定用户
user: "999:999"   # redis 用户的 uid/gid

6.6 安全检查清单

  • 设置了强密码
  • 没有绑定 0.0.0.0(或不映射公网端口)
  • 禁用 / 重命名了危险命令
  • 防火墙限制了访问来源
  • 容器不以 root 运行
  • Redis 版本是最新稳定版

七、高可用方案

7.1 主从复制

一主多从,主节点写,从节点读,读写分离。

docker-compose.yml
bash 复制代码
version: '3.8'

services:
  redis-master:
    image: redis:7.2-alpine
    container_name: redis-master
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./master/conf:/etc/redis
      - ./master/data:/data
    command: redis-server /etc/redis/redis.conf
    networks:
      - redis-net

  redis-slave1:
    image: redis:7.2-alpine
    container_name: redis-slave1
    restart: always
    ports:
      - "6380:6379"
    volumes:
      - ./slave1/conf:/etc/redis
      - ./slave1/data:/data
    command: redis-server /etc/redis/redis.conf --replicaof redis-master 6379
    depends_on:
      - redis-master
    networks:
      - redis-net

  redis-slave2:
    image: redis:7.2-alpine
    container_name: redis-slave2
    restart: always
    ports:
      - "6381:6379"
    volumes:
      - ./slave2/conf:/etc/redis
      - ./slave2/data:/data
    command: redis-server /etc/redis/redis.conf --replicaof redis-master 6379
    depends_on:
      - redis-master
    networks:
      - redis-net

networks:
  redis-net:
    driver: bridge
验证主从
bash 复制代码
# 主节点查看从节点信息
docker exec -it redis-master redis-cli info replication

# 主节点写数据
docker exec -it redis-master redis-cli set master_key hello

# 从节点读数据
docker exec -it redis-slave1 redis-cli get master_key
# "hello" --- 同步成功

7.2 哨兵模式(Sentinel)

主从复制的问题是主节点挂了需要手动切换。哨兵模式实现自动故障转移。

架构
  • 3 个 Sentinel 节点(奇数个,防止脑裂)
  • 1 主 2 从
  • Sentinel 监控主节点,主节点挂了自动选举新主
sentinel.conf
bash 复制代码
# 哨兵端口
port 26379

# 监控的主节点,名称、地址、端口、选举需要的票数
sentinel monitor mymaster redis-master 6379 2

# 主节点密码(如果有)
sentinel auth-pass mymaster your_password

# 主节点下线判断时间(毫秒)
sentinel down-after-milliseconds mymaster 5000

# 故障转移超时时间
sentinel failover-timeout mymaster 10000

# 同步新主节点的从节点数量
sentinel parallel-syncs mymaster 1
docker-compose.yml(哨兵部分)
bash 复制代码
  sentinel1:
    image: redis:7.2-alpine
    container_name: sentinel1
    restart: always
    ports:
      - "26379:26379"
    volumes:
      - ./sentinel1/conf:/etc/redis
    command: redis-sentinel /etc/redis/sentinel.conf
    depends_on:
      - redis-master
      - redis-slave1
      - redis-slave2
    networks:
      - redis-net

  sentinel2:
    image: redis:7.2-alpine
    container_name: sentinel2
    restart: always
    ports:
      - "26380:26379"
    volumes:
      - ./sentinel2/conf:/etc/redis
    command: redis-sentinel /etc/redis/sentinel.conf
    depends_on:
      - redis-master
    networks:
      - redis-net

  sentinel3:
    image: redis:7.2-alpine
    container_name: sentinel3
    restart: always
    ports:
      - "26381:26379"
    volumes:
      - ./sentinel3/conf:/etc/redis
    command: redis-sentinel /etc/redis/sentinel.conf
    depends_on:
      - redis-master
    networks:
      - redis-net
验证哨兵
bash 复制代码
# 查看哨兵状态
docker exec -it sentinel1 redis-cli -p 26379 sentinel master mymaster

# 查看从节点列表
docker exec -it sentinel1 redis-cli -p 26379 sentinel slaves mymaster

# 模拟主节点故障,观察自动切换
docker stop redis-master
# 等几秒后查看新主节点
docker exec -it sentinel1 redis-cli -p 26379 sentinel get-master-addr-by-name mymaster

7.3 集群模式(Cluster)

数据量大、需要水平扩展时用 Redis Cluster,数据分片存储在多个节点上。

注意:Redis Cluster 至少需要 6 个节点(3 主 3 从),单机部署只是测试用,生产环境要分布在不同机器上。


八、常用运维命令

8.1 容器操作

bash 复制代码
# 启动/停止/重启
docker start redis
docker stop redis
docker restart redis

# 进入容器
docker exec -it redis sh

# 查看实时日志
docker logs -f redis
docker logs -f --tail 100 redis

# 查看资源占用
docker stats redis

8.2 Redis 客户端命令

bash 复制代码
# 连接 Redis
docker exec -it redis redis-cli

# 带密码连接
docker exec -it redis redis-cli -a "your_password"

# 连接指定主机端口
docker exec -it redis redis-cli -h 127.0.0.1 -p 6379

8.3 信息查询

bash 复制代码
# 查看服务器信息
127.0.0.1:6379> info

# 查看内存使用
127.0.0.1:6379> info memory

# 查看持久化状态
127.0.0.1:6379> info persistence

# 查看复制信息
127.0.0.1:6379> info replication

# 查看慢查询
127.0.0.1:6379> slowlog get 10

# 查看 key 数量
127.0.0.1:6379> dbsize

8.4 持久化操作

bash 复制代码
# 手动触发 RDB 快照(阻塞式)
127.0.0.1:6379> SAVE

# 后台触发 RDB 快照(非阻塞)
127.0.0.1:6379> BGSAVE

# 手动触发 AOF 重写
127.0.0.1:6379> BGREWRITEAOF

# 查看最后一次持久化时间
127.0.0.1:6379> LASTSAVE

8.5 配置热修改

bash 复制代码
# 查看配置
127.0.0.1:6379> CONFIG GET maxmemory

# 修改配置(临时生效,重启失效)
127.0.0.1:6379> CONFIG SET maxmemory 4gb

# 把当前配置写入配置文件
127.0.0.1:6379> CONFIG REWRITE

九、常见问题与排错

Q1:容器启动后立即退出

大概率是配置文件里 daemonize yes 了,Docker 容器需要前台进程,改成 no

bash 复制代码
# 看日志确认原因
docker logs redis

Q2:启动警告 "WARNING overcommit_memory is set to 0"

bash 复制代码
# 临时解决
sysctl vm.overcommit_memory=1

# 永久解决,写入 /etc/sysctl.conf
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
sysctl -p

Q3:启动警告 "WARNING you have Transparent Huge Pages (THP) support enabled"

bash 复制代码
# 临时关闭
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 永久关闭,写入 rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local

Q4:启动警告 "WARNING: The TCP backlog setting of 511 cannot be enforced"

bash 复制代码
# 调大 somaxconn
sysctl net.core.somaxconn=1024

# docker run 时加参数
--sysctl net.core.somaxconn=1024

Q5:内存满了怎么办

bash 复制代码
# 查看内存使用情况
docker exec -it redis redis-cli info memory

# 查看大 key
docker exec -it redis redis-cli --bigkeys

# 清理过期 key
127.0.0.1:6379> SCAN 0 MATCH * COUNT 1000

# 检查内存淘汰策略是否合理
127.0.0.1:6379> CONFIG GET maxmemory-policy

Q6:RDB 持久化失败

检查数据目录权限,确保 redis 用户有写权限:

bash 复制代码
chown -R 999:999 /data/redis/data

十、性能优化建议

  1. 内存配置 :根据业务量设置 maxmemory,不要让 Redis 用到 swap
  2. 淘汰策略 :缓存场景用 allkeys-lruallkeys-lfu,比 volatile-lru 更稳妥
  3. 持久化策略:RDB + AOF 混合模式,平衡数据安全和性能
  4. 关闭 THP:透明大页会导致 Redis 延迟波动,必须关
  5. 内存大页 :开启 hugepage 可以减少页表开销,但要注意和 THP 区分
  6. 网络优化 :调大 somaxconntcp_backlog
  7. 慢查询监控:开启慢查询日志,定期排查慢命令
  8. 连接池:客户端使用连接池,避免频繁创建销毁连接
  9. pipeline:批量操作使用 pipeline,减少网络往返
  10. key 设计:避免大 key、热 key,合理设置过期时间

总结

Docker 部署 Redis 三步走:

  1. 测试环境docker run 快速启动,验证功能
  2. 生产环境:配置外置 + 数据卷持久化 + 安全加固
  3. 高可用:主从复制 + 哨兵模式,实现自动故障转移

核心原则:数据持久化、密码必设、危险命令禁用、公网不裸奔、内存有上限

相关推荐
YOU OU4 小时前
Redis基础常识与命令
数据库·redis·缓存
吳所畏惧9 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
赵丙双10 小时前
Redis 概率相关的数据类型
redis
风曦Kisaki13 小时前
#企业级docker私有仓库构建:harbor仓库与阿里云镜像仓库
阿里云·docker·容器
期待着201314 小时前
docker 安装 ,在centos7.9
运维·docker·容器
Y38153266214 小时前
SERP API + Redis 缓存层:4 种方案对比与选型
数据库·redis·缓存
骑上单车去旅行16 小时前
Docker Compose 命令完全指南:从构建到运维
docker·容器·eureka
海兰16 小时前
【高速缓存】RedisVL 高级查询(全文搜索、混合搜索和 多向量搜索)
数据库·人工智能·redis·缓存
spider_xcxc17 小时前
K8s 部署学习笔记
docker·容器·kubernetes·云计算·k8s