
在容器里跑 Redis 这件事看着只是敲一条docker run真到不同环境里落地坑就一层一层冒出来了。有人在本地开发机上三分钟就跑通了也有人在内网服务器上卡了一整天镜像拉不下来、配置文件挂载错了、重启后数据没了、容器起来了却连不上。我自己就经历过把测试环境的 Redis 容器直接搬到客户内网结果对方机器不通外网只能现场做镜像搬运的窘境。这篇就把“Docker 安装 Redis”这条路上我实际用过的三种方式完整摊开普通安装拉起即用适合快速验证、在线安装联网环境下的工程化部署用 Compose 固化配置、离线安装断网环境下的镜像与依赖搬运。核心关键词就那几个——Docker、Redis、在线安装、离线安装但每一个背后都有具体的参数、目录和判断逻辑我会把“为什么这么选”和“这么做的代价是什么”都讲清楚。不管你是第一次碰 Docker 的运维新人还是天天写 Compose 的老手应该都能从中找到能直接抄的那一段。1. 先把选型这件事想明白1.1 容器里跑 Redis 到底解决了什么问题在裸机上装 Redis 的传统流程是编译源码或者装系统包配 systemd 单元改/etc/redis.conf然后祈祷这台机器上的其他服务别跟它抢端口抢内存。这套流程最大的问题不是难而是不可复制换一台机器环境差异gcc 版本、glibc 版本、依赖库、内核参数就会让同一份配置长出不同结果。容器化把“运行环境”和“应用”打包成了一个东西Redis 需要什么版本的 glibc、什么启动方式、什么目录结构全都在镜像里定死了换机器只需要确认一件事——Docker 能跑。另一个容易被忽略的价值是版本并存。同一台开发机上同时跑 Redis 5 和 Redis 7用来对比不同版本的命令行为、测试客户端兼容性这在裸机时代基本靠编译到不同前缀目录来解决非常别扭。而容器只要两个不同的容器名加两组端口映射就搞定了。我在做旧项目迁移评估时就同时跑过 6.2 和 7.2 两个容器做数据比对省了大量来回切换的成本。当然容器不是没有代价。它会引入一层网络地址转换、一层文件系统挂载、一层资源隔离这三层恰好也是百分之八十“容器里 Redis 出问题”的来源。所以后面每一节我都会反复强调同一件事把数据、配置、日志明确挂到宿主机上让容器的“无状态”和 Redis 的“有状态”这对矛盾被显式处理掉。1.2 三种装法的边界什么时候用哪个我在实际工作里对这三种方式的划分非常清楚不是按“技术难度”分而是按环境是否联网和配置是否需要长期维护来分。安装方式适用场景前置条件配置固化程度典型耗时普通安装本地验证、临时测试、写 demo能拉取镜像低命令行参数为主3~10 分钟在线安装测试/预发/生产单机、需要长期运行能拉取镜像高用配置文件与 Compose20~40 分钟离线安装内网、专网、客户现场有一台能联网的同架构机器取决于你打包了什么30~60 分钟普通安装的本质是“我把关键参数写在命令行里容器删了重来也无所谓”它适合做验证不适合当长期方案因为命令行参数一旦变长到十几项人就会记错。在线安装的本质是“把配置从命令行挪进文件和版本控制里”docker-compose.yml加一份redis.conf下次重建容器只需要两条命令而且这份配置可以提交到代码库做变更记录。离线安装的本质是“把联网这件事挪到另一台机器上完成”你要准备的不只是镜像还有配置文件、目录结构、可能还要包括 Docker 本体。注意这三种方式不是互斥的而是递进关系。绝大多数人在实际项目里走的是“先用普通安装验证可行性再用在线安装固化配置最后按需转成离线包发到内网”。我在客户现场就经常这么干先在外网机器上把整套 Compose 跑通确认无误再打成离线包。1.3 开工前的两个前置决策版本与目录版本选择这件事很多人图省事直接docker pull redis拉下来的就是latest。我的建议是永远带明确版本号比如redis:7.2.5或者至少redis:7.2。原因很简单latest是一个移动靶今天拉的是 7.2半年后重建容器可能就变成 8.0配置项兼容性、持久化文件格式都可能变。我在一个客户环境里见过因为重建容器导致 RDB 文件版本不兼容、数据加载失败的案例追根溯源就是因为用了latest。目录规划同样要在动手前定好。我习惯用统一的前缀比如/opt/docker/redis/下面分三个子目录conf/放redis.conf纳入配置管理data/放 RDB 和 AOF 文件这是唯一需要备份的目录logs/放日志方便排查这么分的好处是无论你用哪种安装方式挂载路径永远不变迁移时只需要搬这三个目录。数据目录尤其重要容器删了重建只要data/还在数据就在。这一点后面每一节都会体现。2. 普通安装十分钟跑通第一条 redis-cli2.1 拉镜像为什么默认推荐带版本号第一步永远是拉镜像。命令本身很平凡docker pull redis:7.2.5但这里有三个值得说的细节。第一拉取失败不一定是网络问题也可能是磁盘空间不足docker pull的解压过程需要预留镜像体积两倍左右的空间Redis 镜像不大约 130MB一般不会触发但如果你的/var/lib/docker分区本来就很紧张就要先df -h看一眼。第二docker images显示的体积是压缩后的实际占用略大做容量规划时别按显示值算死。第三如果你拉过多个 Redis 版本它们会共享底层 layer占用的空间并不是简单相加这点在写文档给同事时容易被误解。拉完之后建议确认一下架构标签docker image inspect redis:7.2.5 | grep Architecture输出amd64或arm64。这一步不是多余的我在 Apple Silicon 的 Mac 上构建的镜像拿到 x86 服务器上跑如果不显式指定--platform linux/amd64就会出现镜像架构不匹配的问题报错信息还挺绕。2.2 一条 docker run 命令的逐参数拆解下面这条命令是我用得最多的一版直接可以抄docker run -d \ --name redis-test \ -p 6379:6379 \ -v /opt/docker/redis/data:/data \ -v /opt/docker/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \ --restart unless-stopped \ --ulimit nofile65535:65535 \ redis:7.2.5 \ redis-server /usr/local/etc/redis/redis.conf逐项拆开看。-d是后台运行不加会占住终端。--name redis-test给容器起名好处是后面可以用名字操作不用记容器 ID。-p 6379:6379是端口映射左边宿主右边容器如果宿主 6379 被占用改成-p 16379:6379即可容器内部始终是 6379。注意不要图省事加--network host虽然那样能省掉端口映射但会丢失网络隔离还会和你宿主上其他服务抢端口得不偿失。两个-v是关键。第一个把数据目录挂出来Redis 的 RDB 文件dump.rdb和 7.x 之后的 AOF 目录appendonlydir/都落在/data下挂出来数据才不会随容器消失。第二个把配置文件挂进去容器内路径是/usr/local/etc/redis/redis.conf这是 Redis 官方镜像约定的位置你也可以放别的路径但最后启动命令里的路径要跟着改。--restart unless-stopped是我强烈建议加的它决定了机器重启后容器是否自动起来。不写的话宿主机重启后容器是停的线上环境这一点很致命。--ulimit nofile65535:65535解决的是连接数上限问题Redis 的maxclients默认 10000但会受进程文件描述符限制容器默认的 nofile 往往只有 1024 甚至 65536 的一半量小的时候看不出问题压测时就会冒max number of clients reached。最后那行redis-server /usr/local/etc/redis/redis.conf是覆盖镜像默认的启动命令让 Redis 用你的配置文件启动。如果你只是想验证其实可以省略这行镜像会自动用内置默认配置但默认配置没有密码、没有持久化调优、bind 的是所有地址只能用在自己电脑上临时玩。2.3 验证容器、日志、客户端三层确认启动之后不要急着连客户端先做三层确认顺序不能反。第一层容器状态。docker ps看 STATUS 列是不是Up如果显示Restarting或者Exited (1)说明启动就失败了直接docker logs --tail 50 redis-test看报错最常见的是配置文件路径写错、配置文件语法错误、端口被占用。我在第一次用挂载配置文件时就踩过一个坑本地新建的redis.conf在 Windows 上编辑过带了 BOM 头Redis 解析第一行报错直接退出排查了半天才发现是编辑器的问题。所以配置文件尽量用 Linux 环境或vim编辑别用记事本。第二层日志。docker logs redis-test正常应该看到类似这样的输出1:M 12 Aug 2025 10:12:33.123 * Ready to accept connections tcp看到Ready to accept connections就说明服务起来了。如果有Warning: no config file specified之类的提示说明你的配置文件没被读到检查挂载路径。如果看到The server is now ready to accept connections前面还有WARNING overcommit_memory is set to 0那是内核参数警告暂时不影响使用后面第 5 章会讲怎么处理。第三层客户端连接。宿主机上如果装了redis-cli直接redis-cli -h 127.0.0.1 -p 6379 ping返回PONG就成了。如果没装用容器自带的客户端docker exec -it redis-test redis-cli ping。这一步能过说明整条链路端口映射、Redis 进程、网络绑定是通的。2.4 这个阶段最容易踩的三个坑坑一挂载的是目录却当文件用。Docker 挂载时如果宿主机上/opt/docker/redis/conf/redis.conf这个路径不存在Docker 会自动创建一个同名目录挂进去于是容器里的配置文件变成一个目录Redis 启动时报“配置不是文件”。解决办法是挂载前先touch出这个空文件或者用-v 目录:目录的整目录挂载方式。这是新手最高频的错误没有之一。坑二改配置不生效。挂载的配置文件改完之后docker restart才会重新读取docker restart会重启进程配置生效。但如果你的启动命令里写的是容器内的某个路径改的却是宿主机另一个路径那改什么都不会生效先docker inspect redis-test确认挂载源和目标对不对。坑三数据目录权限问题。有些环境里 Docker 以非 root 用户运行或者挂载的宿主机目录属主不对Redis 写入 RDB 时会报Failed opening the RDB file dump.rdb for saving: Permission denied。解决办法是给数据目录放权或者确认容器内运行 Redis 的用户对/data有写权限Redis 官方镜像默认以 root 运行一般不会遇到自定义镜像时才会。3. 在线安装用 Compose 把配置固化下来3.1 为什么过了试用期就该换 Compose普通安装最大的问题是参数的不可见性。一条几百个字符的docker run命令两个月后你自己都记不清当时的--ulimit设成多少了。用docker inspect能查回来但那是逆向工程不是配置管理。Compose 的价值在于把所有这些参数写进一个可读的 YAML 文件放进版本控制改了什么一目了然重建容器只需要docker compose up -d。还有一个更实际的理由多服务编排。真实的项目里 Redis 很少单独存在旁边往往还有 MySQL、Nginx、应用服务。用docker run管理五个容器每次启动都得按顺序敲五条命令出错概率极高。Compose 一个文件描述清楚依赖关系、网络、数据卷一条命令全部拉起来。即使你现在只需要 Redis提前用 Compose 组织后续加服务不会手忙脚乱。这里明确一下所谓“在线安装”指的是在整个安装过程中需要访问网络拉取镜像、有时还需要在线获取依赖的环境区别于完全断网的离线场景。配置的复杂度和是否联网是两回事我在联网环境下同样会用 Compose 加自定义配置这套做法直接复制到离线环境也成立只是镜像来源换成了本地导入。3.2 手写一份能上生产的 redis.conf网上抄来的配置文件大多只有几行能跑但不安全。下面这份是我在单机生产环境里实际用的一版关键项都加了注释你可以按需删减# 网络与访问控制 bind 0.0.0.0 protected-mode yes port 6379 timeout 300 tcp-keepalive 300 tcp-backlog 511 # 认证务必设置强密码 requirepass YourStrongPassword_ChangeMe # 通用 daemonize no loglevel notice databases 16 # RDB 持久化900 秒内至少 1 个键变化就触发 save 900 1 save 300 10 save 60 10000 rdbcompression yes dbfilename dump.rdb dir /data # AOF 持久化 appendonly yes appendfilename appendonly.aof appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 内存管理 maxmemory 2gb maxmemory-policy allkeys-lru # 慢查询 slowlog-log-slower-than 10000 slowlog-max-len 128几个参数值得展开说。bind 0.0.0.0让 Redis 监听所有网卡这在容器里是必要的因为容器需要从外部宿主机或其他容器访问但必须配合requirepass否则等于把没有密码的 Redis 暴露在网络里这是历史上大量 Redis 被入侵的根源。protected-mode yes是最后一道防线在没有密码且没有显式 bind 的情况下会拒绝外部连接两者配合使用最稳妥。maxmemory是我最建议显式设置的一项。不设置的话Redis 会一直吃内存直到触发系统 OOM容器可能被内核直接杀掉日志里只留一句模糊的Killed。设置多少合适我的经验值是宿主机或容器内存上限的 60% 到 70%。比如给容器分配 4GBmaxmemory设 2.5GB 到 2.8GB 比较合适剩下的空间要留给AOF 重写时的 fork 子进程、RDB 保存时的写时复制内存、客户端缓冲区、以及 Redis 自身的开销。如果你设成 100%一旦触发持久化就极可能被 OOM Killer 干掉。maxmemory-policy选了allkeys-lru意味着内存满了之后淘汰最近最少使用的键适合当缓存用的场景如果 Redis 里存的是不能丢的数据改成noeviction让它写不进去直接报错比默默淘汰数据更安全。appendonly yes和appendfsync everysec这一对组合是我在“可靠性”和“性能”之间的默认选择。everysec表示每秒刷一次盘极端情况下最多丢一秒的数据性能损耗可以接受。如果业务能接受丢更多用no让操作系统决定刷盘时机性能最好如果一秒都不能丢用always代价是每条写命令都要等磁盘吞吐会明显下降。3.3 docker-compose.yml 与目录结构配置文件的目录结构我建议这样组织/opt/docker/redis/ ├── docker-compose.yml ├── conf/ │ └── redis.conf ├── data/ └── logs/对应的docker-compose.ymlservices: redis: image: redis:7.2.5 container_name: redis restart: unless-stopped ports: - 6379:6379 volumes: - ./conf/redis.conf:/usr/local/etc/redis/redis.conf:ro - ./data:/data - ./logs:/logs command: [redis-server, /usr/local/etc/redis/redis.conf] ulimits: nofile: soft: 65535 hard: 65535 environment: - TZAsia/Shanghai healthcheck: test: [CMD, redis-cli, -a, YourStrongPassword_ChangeMe, ping] interval: 30s timeout: 5s retries: 3 start_period: 10s这里有几个细节是踩过坑才知道的。配置文件挂载加了:ro表示只读防止容器内进程误写配置这是个小习惯但很有用。healthcheck里的密码如果直接写在test里docker inspect能查到追求安全的话可以用环境变量加$$转义的方式注入或者干脆接受这个风险——健康检查本身是为了让编排系统知道服务是否可用代价是要暴露密码。environment里的TZ会影响容器内日志的时间戳不设的话日志都是 UTC排查问题时容易和本地时间对不上我在一次跨时区协作的排查里就因为这个把时间线搞错了半小时。3.4 启动、验证与日常运维命令启动就一条cd /opt/docker/redis docker compose up -d验证分几步。看状态docker compose ps服务应该是running (healthy)注意括号里的 healthy这是 healthcheck 通过的意思不通过会显示unhealthy。看日志docker compose logs -f redis看到Ready to accept connections即可。连客户端docker exec -it redis redis-cli -a YourStrongPassword_ChangeMe ping返回PONG。日常运维我常用的几条# 查看实时日志 docker compose logs -f --tail 100 redis # 进入 redis-cli 交互式命令行 docker exec -it redis redis-cli -a YourStrongPassword_ChangeMe # 查看内存使用概况 docker exec redis redis-cli -a YourStrongPassword_ChangeMe info memory # 触发一次 RDB 保存 docker exec redis redis-cli -a YourStrongPassword_ChangeMe bgsave # 重建容器改配置后 docker compose up -d --force-recreate注意redis-cli -a会把密码出现在命令历史和进程列表里生产环境更推荐用REDISCLI_AUTH环境变量传入或者配置~/.rediscli避免密码被ps看到。这是个容易被忽视的安全细节。3.5 持久化策略RDB 与 AOF 怎么选这两种机制经常被混着讲我用一句话区分RDB 是定期拍快照AOF 是记账本。RDB 把某一时刻的全量数据写成一个紧凑的二进制文件恢复快、体积小但两次快照之间的数据会丢。AOF 追加记录每一条写命令丢数据少但文件大、恢复慢。维度RDBAOF数据安全性较低可能丢几分钟数据高最多丢 1 秒everysec文件体积小压缩存储大是实际写入量的数倍恢复速度快慢要重放所有命令对性能影响fork 时瞬时抖动持续的小量 I/O适用场景缓存、可重建数据重要数据、要求低丢失我的默认策略是两个都开这不是浪费。Redis 4.0 之后支持混合持久化aof-use-rdb-preamble yes7.x 默认开启AOF 重写时用 RDB 格式写前半部分命令追加在后面兼顾了恢复速度和数据安全。开了这个之后重启恢复会先加载 AOF 文件体积比纯 AOF 小得多。需要提醒的是RDB 保存和 AOF 重写都会 fork 子进程而 fork 在 Linux 上是写时复制如果此时实例内存占用很大fork 过程本身会阻塞主线程。经验数据是每 GB 内存大约阻塞 10 到 20 毫秒一个 20GB 的实例 fork 一次可能阻塞几百毫秒对延迟敏感的业务要提前评估。这也是为什么我不建议把maxmemory设得太接近物理内存上限的原因之一。4. 离线安装断网机器上的镜像搬运4.1 整体思路把“联网”这件事挪到别的机器上离线安装的核心逻辑只有一个所有需要网络的动作都在一台能联网的机器上完成产出一个自包含的文件包搬到目标机器上解包即用。需要联网的动作通常包括三件拉 Docker 镜像、下载配置文件模板、以及如果需要安装 Docker 本体本身。这里有个前提条件必须先确认两台机器的 CPU 架构要一致。联网机器是 x86_64目标机器是 ARM比如某些国产化芯片服务器镜像直接搬过去是跑不起来的。确认方法是两边都执行uname -m输出不一致就要在导出镜像时用--platform指定目标架构前提是镜像仓库里有对应架构的版本。这一点在信创环境里极其常见也是离线迁移失败的头号原因我踩过至少两次。第二件要确认的事是目标机器是否已有 Docker。有的话跳过安装直接搬镜像没有的话离线安装 Docker 本体又是另一个话题4.4 节会专门讲。先把这两件事确认清楚再往下走否则会做大量无用功。4.2 在联网机器上导出镜像与配置文件第一步在联网机器上拉取和测试环境完全一致的镜像版本docker pull redis:7.2.5第二步把镜像导出成 tar 文件。注意这里有个坑导出时用的镜像名和标签导入后会原样保留所以名字要写全docker save -o redis-7.2.5.tar redis:7.2.5导出完成后看一下文件大小ls -lh redis-7.2.5.tarRedis 镜像大概在 130MB 到 140MB 左右。如果发现是几百 MB可能是把别的镜像一起打了说明镜像名写错了比如写成了redis却匹配到多个 tag 的合并。第三步准备配置文件和目录结构。我建议在联网机器上就把整个部署目录搭好打包成一个整体mkdir -p redis-offline/{conf,data,logs} cp /opt/docker/redis/conf/redis.conf redis-offline/conf/ cp /opt/docker/redis/docker-compose.yml redis-offline/ tar -czf redis-offline-pkg.tar.gz redis-offline/ redis-7.2.5.tar这样做的好处是目标机器上解包之后目录结构、配置文件、Compose 文件全都在不需要现场手动创建。我在客户现场用这种方式从解压到服务起来大概五分钟比现场手忙脚乱地敲命令稳得多。注意配置文件里的maxmemory、requirepass这类参数是按联网机器环境调的搬到目标机器前要先核对一遍硬件规格和密码策略。我有一次直接把测试环境的配置搬过去maxmemory设的是 512MB结果客户的生产机器是 32GB 内存Redis 跑起来性能没发挥出来被追问了好一阵。4.3 传输与落地的完整步骤传输方式看环境U 盘、内网文件服务器、scp都行。如果目标机器能通过内网访问scp redis-offline-pkg.tar.gz usertarget:/tmp/最方便。落地步骤如下# 1. 解压 cd /tmp tar -xzf redis-offline-pkg.tar.gz # 2. 导入镜像 docker load -i /tmp/redis-7.2.5.tar # 3. 确认镜像导入成功 docker images | grep redis # 4. 把部署目录挪到最终位置 mkdir -p /opt/docker mv /tmp/redis-offline /opt/docker/redis # 5. 启动 cd /opt/docker/redis docker compose up -ddocker load的输出会显示Loaded image: redis:7.2.5这一行确认了就说明镜像完整导入。如果导入报错最常见的原因是 tar 文件在传输过程中损坏用md5sum或sha256sum两边比对一下校验值就能定位。这个习惯在离线场景里特别值得养成我现在的做法是导出后立刻算一次校验值写在一个checksum.txt里一起打包落地时先校验再导入。启动后按第 3 章的方法验证docker compose ps、docker compose logs、docker exec redis redis-cli -a 密码 ping。这里有个离线场景特有的坑如果配置文件里有bind之外的域名或外部依赖容器可能启动成功但服务异常比如配置了replicaof指向某个外网主节点内网里解析不到就会一直重试。落地前把所有指向外部的配置项都过一遍。4.4 目标机器没有 Docker 怎么办这是离线安装里最麻烦的分支。目标机器既没有 Redis 镜像也没有 Docker你需要在断网环境里先把 Docker 装起来。常见的两条路第一条是系统包方式。如果目标机器有操作系统安装盘或者内网软件源里面有 Docker 相关的包不同发行版的包名不一样用它是最省事的因为依赖关系由包管理器处理。但如果内网源不完整包之间的依赖会让你陷入“装 A 缺 B、装 B 缺 C”的循环这时候需要在一台同版本系统的联网机器上把依赖一起下载好比如用yumdownloader --resolve把主包和依赖全部下载到本地目录再整体拷贝过去离线安装。第二条是静态二进制方式。Docker 官方提供免安装的静态二进制压缩包解压后是一堆可执行文件手动放到系统路径、配置好守护进程的启动项就能用。这种方式的好处是不依赖系统包管理器坏处是需要手动处理几件事把可执行文件复制到系统路径、设置可执行权限、创建守护进程的配置文件、把守护进程加入开机启动。我在几台国产化系统上就是用这个方式装的步骤不复杂但对细节要求高尤其是守护进程的配置项写错会导致启动失败且日志不明显。无论走哪条路提前在联网机器上把包下全、把步骤写清、把每一步的验证命令记下来是离线安装能否一次成功的关键。我现在的习惯是把这些步骤写成一个 shell 脚本脚本里每一行都带echo提示现场执行时看输出就知道走到哪一步出了问题。4.5 离线安装的校验清单落地之后别急着交给业务按这个清单过一遍镜像版本是否与预期一致docker images --format {{.Repository}}:{{.Tag}} | grep redis容器状态是否 healthydocker compose ps数据目录是否真的在写ls -lh /opt/docker/redis/data/写入几条数据后应该能看到dump.rdb或appendonlydir/密码是否生效不带密码执行redis-cli ping应该报NOAUTH Authentication required端口是否只对需要的人开放ss -lntp | grep 6379确认没有意外暴露到公网重启后是否自动恢复reboot太重用docker restart redis模拟确认数据还在这六项都过了才算是真正装完。少一项都可能在某个不确定的时刻给你惊喜。5. 常见问题与排查技巧实录5.1 启动阶段问题速查表现象可能原因排查命令解决办法容器 Exited (1) 后不断重启配置文件路径错或语法错docker logs redis核对挂载路径检查配置项拼写报“不是一个文件”挂载时宿主机文件不存在被创建成目录ls -ld /path/redis.conf先touch出文件再挂载端口被占用宿主已有服务占用 6379ss -lntp | grep 6379换映射端口如16379:6379镜像导入后架构不匹配导出与目标架构不同uname -m两边比对重新导出指定--platformcompose 报语法错误YAML 缩进用了 Tab肉眼检查或docker compose config改成空格缩进docker compose config这个命令值得单独说一句它会把你的 YAML 解析一遍并输出最终生效的配置缩进错误、字段名拼错都会在这里报出来。我在写完 Compose 文件后习惯先跑一次它比直接up再排错高效得多。5.2 连接与认证类问题“容器起来了但连不上”这句话背后的原因可以排出一整张表。先分清连接来源从宿主机连、从其他容器连、从外部机器连三种情况排查路径完全不同。从宿主机连不上先看端口映射对不对docker port redis会显示映射关系如果什么都没输出说明-p没生效或者当前容器没对外暴露端口。再看 Redis 是否真的在监听docker exec redis ss -lntp应该能看到 6379 处于 LISTEN。如果 Redis 只监听了127.0.0.1而不是0.0.0.0那是配置文件里bind写错了容器内的127.0.0.1和宿主机的127.0.0.1不是一回事这是很多人卡住的地方。从其他容器连不上问题往往在网络上。默认情况下容器各自在独立的 bridge 网络里互相看不见。解决办法是把它们放进同一个自定义网络在 Compose 里给每个服务配同一个networks然后用服务名而不是 IP 互相访问因为容器 IP 是动态的写死迟早出问题。从外部机器连不上优先怀疑防火墙。宿主机层面系统防火墙或安全组没放行 6379 端口容器里再怎么配都没用。这个顺序不要搞反先确认网络层通了再查 Redis 层。认证类问题相对简单NOAUTH Authentication required是没传密码ERR invalid password是密码错了ERR Client sent AUTH, but no password is set是服务端根本没设密码而你却传了。第三种情况常见于配置改了但没重启容器或者挂载的配置文件没生效回头检查 2.4 节提到的挂载路径问题。5.3 数据与持久化类问题“数据重启后没了”是仅次于“连不上”的高频问题。排查顺序这样走第一确认数据目录挂载了吗docker inspect redis | grep -A5 Mounts如果/data没有对应的宿主机路径那数据就写在容器可写层里容器一删自然就没了。第二确认持久化开了吗docker exec redis redis-cli -a 密码 config get appendonly返回no说明 AOF 没开再看config get save如果返回空数组说明 RDB 也关了。第三确认数据目录权限对不对写入被拒绝时日志里会有明显提示。关于持久化的一个常见误解是“我开了 AOF 就一定不丢数据”。实际上appendfsync everysec是每秒刷盘断电情况下最多丢一秒这个“最多”是理论值实测中如果磁盘压力大刷盘延迟可能超过一秒。要真的一秒都不丢得用always但吞吐会掉一个数量级。业务上更务实的做法是重要数据在应用层做双写或者用更可靠的存储Redis 只作为加速层。备份这件事我要单独强调。有了持久化不等于有了备份RDB 文件如果被误删、磁盘损坏数据一样丢。我的做法是加一个定时任务每小时把/data下的持久化文件复制到一个独立的备份目录保留最近若干份。如果是 Compose 管理也可以起一个专门的备份容器来干这件事但最简单的还是宿主机的计划任务加cp够用且不容易出错。5.4 性能与系统参数类问题如果日志里出现WARNING overcommit_memory is set to 0说明内核的内存过载策略可能导致bgsave时 fork 失败。解决办法是在宿主机上执行sysctl vm.overcommit_memory1并写入配置文件让它重启后依然生效。这里的1表示“总是允许内存分配”听起来很激进但对 Redis 这种依赖 fork 的进程来说是标准做法。另一个常见警告是WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128。意思是配置文件里写了 511但内核上限只有 128实际生效的是 128。解决办法是调大内核参数net.core.somaxconn1024。这个参数影响的是高并发下连接建立的排队能力量小的时候感知不到压测时可能出现连接被拒。还有一个隐蔽的性能问题来自透明大页THP。开启 THP 时Redis 的 fork 和内存访问会出现延迟抖动官方建议关闭。宿主机上执行echo never /sys/kernel/mm/transparent_hugepage/enabled并持久化。我在一台延迟抖动明显的机器上关掉 THP 后P99 延迟确实降下来了这个改善不是心理作用。内核参数推荐值影响vm.overcommit_memory1fork 成功率和 bgsave 稳定性net.core.somaxconn1024高并发连接建立能力transparent_hugepagenever降低延迟抖动容器 ulimit nofile65535最大客户端连接数这四个参数我在每台新机器上都会检查一遍加起来花不了两分钟但能省掉后面很多莫名其妙的故障排查。6. 几个我认为值得记住的经验密码这件事上我吃过一次不小的亏。早期一个测试环境图方便没设密码只在内网开着觉得“内网很安全”。后来做安全扫描时发现那个端口实际上能通过某条链路被外部访问到虽然没造成实际损失但那次之后我所有环境的 Redis 都强制设密码包括本地开发。密码强度不用太夸张但一定不能是空或者123456。这件事没有例外。除了密码之外我还建议养成一个习惯把每个 Redis 实例的部署信息写在一个 README 里包括镜像版本、挂载路径、端口、密码存放位置、备份策略、内核参数。听起来很基础但当你半年后接手一台别人搭的机器或者自己回看三个月前的部署这份文档能省掉大量猜测。我在团队里推广这个做法之后处理“某个 Redis 数据不对”这类问题的平均时间至少缩短了一半。最后关于三种安装方式的选择我的判断标准很朴素能不能一次做成、能不能被别人复现、出问题能不能自己查清楚。普通安装满足“一次做成”但难复现在线安装三者兼顾离线安装则是环境所迫。搞清楚你面对的是哪种约束选哪种方式就不会纠结了。