尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WSL+Docker环境下的Redis备份与迁移完整方案

WSL+Docker环境下的Redis备份与迁移完整方案 平时在 WSL 里用 Docker 跑 Redis 做本地开发、小项目缓存已经成了我这边一个挺顺手的工作流。但“顺手”背后有个很容易被忽略的问题一旦 WSL 的发行版坏了、Docker 数据卷被误删、或者你要换一台电脑Redis 里缓存的数据怎么保住、怎么迁走这个坑我踩过不止一次所以后来专门整理了一套在 WSLDocker 环境下的 Redis 备份与迁移方案今天完整分享出来希望对正在用这套组合的你有帮助。这套内容适合这几类读者本地开发环境用 WSL2 跑 Docker Desktop、或者直接在 WSL 发行版里装 Docker 的开发者负责维护 Redis 数据、但不想用企业级重方案的中小型项目负责人还有那些准备换电脑、迁移开发环境的同学。我会把原理、操作步骤、常见坑都串起来讲争取让你看完之后能直接照着做。1. 环境现状WSL、Docker 和 Redis 到底是怎么组合的1.1 WSL 里跑 Docker 的两种路线WSL 本身只是一个 Linux 兼容层目前主流用的都是 WSL2它背后是一个真正的轻量虚拟机。在这上面跑 Docker常见的有两条路线。一条是使用Docker Desktop它会自动对接 WSL2 的后端安装完以后在 Windows 的托盘里可以直接管理容器。这种方式对大多数人来说最省心Docker Desktop 会帮你把 Docker CLI、守护进程、网络环境都处理好终端里直接敲docker ps就能用。另一条是不装 Docker Desktop直接在 WSL 发行版内部署 docker-engine。这种方式更贴近纯 Linux 服务器环境内存占用更小不依赖 Windows 侧的服务托管。我个人的选择是后者因为我的 WSL 发行版平时还要做别的 Linux 开发和编译整套都跑在发行版里逻辑更干净。但这条路线需要自己处理 systemd 或 service 的启动方式否则每次进入 WSL 都要手动启动 dockerd稍微麻烦一些。1.2 为什么 Redis 容易造成“备份盲区”Redis 给很多人的第一印象是一个“缓存”丢一点数据似乎无所谓。但实际用起来就会发现很多项目会把会话信息、临时验证码、排行榜、甚至是部分业务配置都存在 Redis 里。一旦 WSL 出问题比如 VHDX 虚拟磁盘损坏、发行版被重置、Docker 数据卷意外删除这些数据就全没了。更麻烦的是WSL 的默认磁盘格式是一个 VHDX 文件如果你不做定期备份这个文件本身也可能因为意外断电、Windows 更新失败等出现异常。所以说Redis 虽然轻量但备份环节绝对不能省。而且正因为很多人觉得它“就是缓存”反而最容易成为数据丢失的重灾区。我的建议是早点把 Redis 备份纳入日常任务不管你是本地开发还是服务器运维至少要做到“有备可恢复”。这篇文章后面讲的是一套不依赖付费工具、直接用 Docker 命令和 Redis 自带机制完成的备份迁移方案成本很低但关键时刻能救命。2. 备份方案设计先搞懂 Redis 持久化和容器数据卷的关系2.1 Redis 的 RDB 和 AOF两种持久化机制的区别在做备份之前得先把 Redis 自身的持久化机制搞清楚。简单说Redis 提供两种持久化方式分别是 RDB快照和 AOF追加日志。RDB 是内存数据的二进制快照通常生成.rdb文件。它的优点是文件紧凑、加载速度快适合做周期性的全量备份。缺点是如果 Redis 异常退出两次快照之间的数据会丢失。AOF 则是把每一条写命令追加到日志文件里恢复时重放这些命令数据完整性更高但文件体积会越来越大恢复速度也相对慢一些。在实际环境里很多人会同时开启两者或者根据业务容忍度来选择。我的本地项目一般容忍度较高所以多数时候只开 RDB但到了要迁移数据的时候我会临时把 AOF 也打开或者干脆在备份前执行一次SAVE或BGSAVE确保拿到的是最新快照。2.2 Docker 数据卷Redis 数据到底存在哪里用 Docker 跑 Redis 时如果不对数据目录做特殊处理容器内部存放数据的/data目录会随着容器删除而消失这正是很多人丢数据的根源。正确做法是用数据卷或者 bind mount 把容器内的/data目录映射到宿主机。比如我常用的一段 docker-compose 配置是这样的services: redis: image: redis:7.2 container_name: redis-local restart: unless-stopped ports: - 6379:6379 volumes: - redis-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf:ro command: [redis-server, /usr/local/etc/redis/redis.conf] volumes: redis-data:这样配置之后Redis 的 RDB 快照和 AOF 日志都会写到名为redis-data的 volume 里。volume 在 Docker 的托管目录下WSL 的发行版里路径通常类似于/var/lib/docker/volumes/redis-data/_data。备份 Redis本质就是备份这个目录下的持久化文件。注意使用 bind mount 把 Redis 数据目录挂载到 Windows 文件系统比如/mnt/c下的某个目录时读写性能会比较差不建议在生产环境使用。2.3 备份频率和保留策略别让备份文件成为另一个包袱备份频率得看数据变化速度。如果你只是本地开发数据量不大每天跑一次全量备份就够了如果 Redis 里有偏实时性的业务数据那就要考虑每半小时甚至更频繁地备份。我常用的策略是保留最近 7 天的每日备份以及最近 4 周的每周备份。备份文件名里带上日期比如redis-data-backup-2026-05-20.tar.gz。这样即使某次备份文件损坏也能往前恢复。这个策略不复杂但能避免“备份了但不知道能不能恢复”的尴尬。3. 操作篇WSL 环境下 Redis 数据备份的完整流程3.1 备份前准备检查数据目录和持久化状态备份之前先确认几件事容器是否正常运行、Redis 数据落在哪个路径、以及是否已经开启了持久化。先查看运行中的容器docker ps | grep redis然后进入容器用 Redis 命令确认持久化配置docker exec -it redis-local redis-cli CONFIG GET save docker exec -it redis-local redis-cli CONFIG GET appendonly如果save返回的是空说明 RDB 快照没有开启如果appendonly返回no说明 AOF 也没开。此时直接备份数据卷虽然也能备份到当前已有的 RDB 文件但拿到的可能是旧数据所以需要先触发一次手动快照。触发手动快照有两种命令SAVE会阻塞 Redis 主线程适合数据量小的时候BGSAVE会 fork 子进程后台生成快照更适合线上环境。本地项目我一般直接执行BGSAVEdocker exec redis-local redis-cli BGSAVE执行后可以通过LASTSAVE检查时间戳确认快照确实生成了docker exec redis-local redis-cli LASTSAVE3.2 用 docker run 一次把数据卷打包出来确认数据已经写入/data之后需要把数据卷里的文件完整导出来。最稳妥的备份方式是直接打包 volume 目录。这里我用一个临时容器把数据卷挂载进去然后执行tar打包。docker run --rm -v redis-data:/data -v /home/user/backup:/backup ubuntu tar czf /backup/redis-data-backup-$(date %Y%m%d).tar.gz -C /data .这条命令做了什么它启动了一个临时的 ubuntu 容器把redis-data卷挂载到容器内的/data把宿主机/home/user/backup挂载到容器内的/backup然后执行tar czf打包/data目录下的所有内容最终在宿主机/home/user/backup目录下生成带日期的压缩包。如果不想额外拉 ubuntu 镜像可以直接用 Redis 镜像自带的 shell操作方式一样。甚至是直接docker cp也能把/data目录复制出来不过 copy 出来的文件权限和目录结构会有些差异不够打包成单文件来得干净。3.3 只备份 RDB 文件是否足够怎么取舍直接备份整个/data目录是最保险的因为它同时涵盖 RDB 和 AOF 文件。但如果你的场景比较明确比如只想保留一个可以快速恢复的全量快照那也可以只备份dump.rdb文件。只备份 RDB 的好处是文件小、恢复快、结构简单缺点是如果开启了 AOF恢复时可能无法完全还原到最后时刻的数据。在很多本地开发场景下这个数据精度完全够用了。我的建议是如果是本地开发环境只备份 RDB 文件就够了简单高效如果 Redis 里有业务数据最好连 AOF 一起备份至少不要漏掉持久化文件。3.4 定时备份利用 WSL 的 cron 做到自动化手动备份虽然稳妥但容易忘。WSL 本身可以运行 cron所以我们可以写一个简单的脚本把备份流程自动化。先在 WSL 里创建备份脚本比如/home/user/scripts/backup-redis.sh#!/bin/bash # Redis容器名称 REDIS_CONTAINERredis-local # 备份文件保存路径 BACKUP_DIR/home/user/backup # 保留天数 KEEP_DAYS7 # 确保备份目录存在 mkdir -p $BACKUP_DIR # 触发RDB快照并稍作等待 docker exec $REDIS_CONTAINER redis-cli BGSAVE sleep 2 # 打包数据卷 docker run --rm \ -v redis-data:/data \ -v $BACKUP_DIR:/backup \ ubuntu tar czf /backup/redis-data-$(date %Y%m%d-%H%M%S).tar.gz -C /data . # 清理超过保留天数的备份文件 find $BACKUP_DIR -name redis-data-*.tar.gz -mtime $KEEP_DAYS -delete然后添加执行权限并写入 crontabchmod x /home/user/scripts/backup-redis.sh crontab -e在打开的编辑器中加入一行表示每天凌晨 3 点执行备份0 3 * * * /home/user/scripts/backup-redis.sh如果之前没有在 WSL 里使用过 cron可能需要先启动服务sudo service cron start4. 迁移篇把 Redis 数据搬到新容器、新电脑或新 WSL4.1 场景一同一台机器上迁移到新容器最常见的迁移场景是当前 Redis 容器配置混乱、镜像版本太老或者想换一个 Docker Compose 配置所以打算重建容器。这时只要数据卷还在迁移就非常简单。我的做法是先把旧容器停掉避免写入操作导致数据不一致docker stop redis-local然后直接用数据卷创建新容器关键是挂载同一个 volumedocker run -d \ --name redis-new \ -p 6379:6379 \ -v redis-data:/data \ --restart unless-stopped \ redis:7.2因为数据卷没有变Redis 启动时会自动加载/data下的持久化文件数据自然就“迁移”过去了。整个过程几乎不需要额外步骤唯一要注意的是先停旧容器再起新容器否则两个容器同时挂载同一个卷写同一份数据很容易出问题。4.2 场景二从已有备份文件恢复到新容器如果数据卷已经被误删或者你要从备份文件恢复那就需要先把备份压缩包解压到数据卷里。假设你有一个redis-data-backup-2026-05-20.tar.gz恢复流程如下先创建一个临时容器把备份文件解压到数据卷中docker run --rm \ -v redis-data:/data \ -v /home/user/backup:/backup \ ubuntu bash -c rm -rf /data/* tar xzf /backup/redis-data-backup-2026-05-20.tar.gz -C /data这里先执行rm -rf /data/*是为了避免旧数据残留影响恢复结果。如果你确定数据卷是干净的可以省略这一步。解压之后启动 Redis 容器并挂载redis-data卷Redis 会自动加载数据里的 RDB 文件并恢复数据docker run -d --name redis-restore -p 6379:6379 -v redis-data:/data redis:7.2进入容器检查数据是否完整docker exec -it redis-restore redis-cli DBSIZE如果返回的数字和迁移前一致说明恢复成功。4.3 场景三跨机器、跨 WSL 发行版迁移换电脑或者在两台完全独立的机器之间迁移时备份压缩包就是你的“搬运媒介”。把备份文件拷贝到新机器的某个目录然后在新的 WSL 环境里创建同样的数据卷再解压启动容器步骤和恢复过程完全一致。这里要提醒一点不同机器上的 WSL 发行版、Docker 版本可能不同但 Redis 的 RDB 文件格式有版本兼容性。比如 Redis 7.x 生成的 RDB 文件理论上可以被更新的 Redis 版本加载但低版本 Redis 就不一定兼容高版本的 RDB 文件了。所以跨机器迁移时尽量保证新环境里的 Redis 版本不低于旧环境或者直接用同版本最省心。4.4 另一种迁移思路主从复制临时同步如果不想折腾备份文件和压缩包还有一种在线迁移思路在新环境启动一个 Redis 从节点让它从旧节点同步数据等追平之后再把服务切过去。具体操作是在新环境里配置replicaof指向旧 Redis 的地址和端口docker run -d \ --name redis-new \ -p 6380:6379 \ -v redis-new-data:/data \ redis:7.2 \ redis-server --replicaof 192.168.1.100 6379不过这个方案依赖网络连通性且中间有全量同步和增量同步的过程如果数据量大耗时会比较长。我一般只在两台机器网络条件很好、且希望最小化业务中断时才用。日常场景还是推荐用备份文件迁移。5. 常见问题与排查技巧实录5.1 容器里执行BGSAVE后没有生成新快照如果你执行了BGSAVE但发现dump.rdb的时间戳没变常见的原因有两个一是 Redis 配置里开启了 RDB 但路径不是默认的/data二是 Redis 没有写入/data目录的权限。排查方法很简单先用CONFIG GET dir查看 RDB 文件保存路径docker exec redis-local redis-cli CONFIG GET dir docker exec redis-local redis-cli CONFIG GET dbfilename如果路径不是/data那你的 Redis 数据可能写在容器内其他位置导致数据卷没有覆盖到。这时要么修改配置要么迁移数据目录。这种情况最容易出现在有人用了非官方镜像、或者自定义了 redis.conf 的时候。5.2 WSL 磁盘空间被备份文件占满怎么处理备份文件多了之后WSL 的 VHDX 虚拟磁盘会越占越大。这是因为 WSL2 的虚拟磁盘默认只会扩大不会自动缩小删除文件后空间不一定立刻释放。解决方法是先压缩虚拟磁盘。操作步骤分两步第一步在 WSL 里整理并删除不需要的备份文件确保宿主机上确实不再需要这些空间。第二步在 Windows 的 PowerShell 里执行wsl --shutdown然后找到你的发行版对应的 VHDX 文件路径。一般可以在 WSL 的安装目录或者%LOCALAPPDATA%\Packages\...下面找到确认路径后用diskpart压缩diskpart select vdisk fileC:\path\to\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit压缩之后虚拟磁盘文件会明显变小。这个方法对 Docker 镜像、备份文件等占用的空间释放很有效。5.3 跨机器迁移时出现Bad file format reading the append only file这种情况多半是 AOF 文件损坏或版本不兼容。Redis 启动时如果发现 AOF 文件异常会拒绝启动数据读取不进去。我遇到这个问题的处理方式是检查备份压缩包里是不是同时包含了dump.rdb和appendonly.aof。如果 AOF 文件有异常可以先用redis-check-aof工具修复docker run --rm -v redis-data:/data redis:7.2 redis-check-aof /data/appendonly.aof --fix修复完成后再启动容器。如果 AOF 修复不了就只能退回到 RDB 文件恢复数据。所以我在备份时总会保留 RDB 文件万一 AOF 出问题还能用 RDB 兜底。5.4 备份文件过大tar 压缩耗时太长本地项目数据量通常不大但如果是缓存了大量业务数据Redis 的 RDB 文件可能到达几 GB这时tar czf的压缩时间会明显拉长。我的经验是先用tar直接打包不压缩生成.tar文件等备份传输完后再单独做压缩。或者干脆分卷先用docker cp把/data目录复制出来再手动处理。如果你希望备份尽量快可以把压缩级别降低。比如用 gzip 压缩时指定-1最快压缩tar czf -C /data . --use-compress-programgzip -1。牺牲一点压缩率换取更快的备份速度。5.5 恢复后出现中文乱码或 key 显示异常这是 Redis 客户端显示层面的问题不是数据真的损坏。检查你的终端编码是否支持 UTF-8尤其是 WSL 默认终端有时候会使用 GBK 编码导致中文 key 显示为乱码。我一般会在 VSCode 的集成终端里把编码设置为 UTF-8或者使用redis-cli --raw查看中文 key 的内容。如果数据本身真有问题可以通过redis-cli --scan --pattern *对比 key 的数量和几个关键 key 的内容来判断。6. 一点经验之谈备份脚本之外我更看重“恢复演练”备份策略做得再好如果从没有实际恢复过心里始终不踏实。我现在每个月至少会做一次“恢复演练”把最新的备份文件拿到一个临时目录里启动一个全新的 Redis 容器把备份解压进去然后用业务里的几个关键查询去验证数据是否可用。这个习惯帮我发现过很多隐藏问题比如备份文件不完整、压缩包解压后目录层级错误、Redis 版本不兼容等。如果你只备份不恢复这些坑迟早会在你最不想出问题的时候跳出来。另外还有一个地方值得多说一句WSL 环境里的 Docker 卷虽然看起来只是个目录但它的权限和文件所有权可能和普通目录不一样备份文件放到 Windows 共享目录或拷贝到 U 盘时注意别弄丢权限位。如果恢复后发现 Redis 启动报权限问题先看/data目录归属对不对通常让 Redis 容器使用 root 或与旧容器相同的 UID/GID 就能解决。Redis 备份和迁移这事说难不难说简单也不简单。最重要的其实不是掌握多少命令而是形成一套自己能信得过的流程确认数据目录、定期触发快照、打包存档、定期验证恢复。只要把这几个关键环节做扎实了不管本地开发还是小规模生产心里都能有底。
返回列表