Files
cs-note/hhs/Redis/04-RDB持久化.md
T
2026-05-24 11:42:38 +08:00

24 KiB
Raw Blame History

tags, create time
tags create time
Redis
缓存
持久化
RDB
2026-05-15 18:12

RDB 持久化

概述

[!QUESTION] Redis 的数据都存在内存里,那服务器一断电,数据岂不是全没了? 没错——这就是持久化存在的意义。Redis 提供两种持久化方案:RDB 和 AOF,本文先讲 RDB。

[!SUMMARY] 一句话理解 RDB RDB(Redis Database)就是在某个时间点,把 Redis 内存中的全部数据"拍一张照片"存到磁盘上——这个"照片"就是一个 .rdb 快照文件。

你可以把它想象成游戏存档:打 Boss 之前你手动存了一次档,万一翻车了可以读档重来。但代价是——存档之后到翻车之间的操作全丢了。

核心特点

特性 说明 类比
⚡ 恢复极快 二进制文件直接加载到内存,跳过命令回放 像从压缩包解压,比照着菜谱重新做菜快得多
📦 文件紧凑 使用 LZF 压缩,远小于等量 AOF 日志 一张照片的信息量 > 千言万语的描述
🔧 架构简单 无额外复杂逻辑,一个文件搞定备份/迁移 "复制-粘贴"级别的简单
⚠️ 数据窗口丢失 两次快照之间的写操作不可恢复 存档点之后的操作无法回溯

何时使用

  • 大数据集冷备:定期全量备份到 S3 / OSS,作为最后一道防线
  • 灾难恢复:服务器挂了?把 .rdb 文件丢到新机器上,秒级恢复
  • 大规模数据场景:当你的 Redis 存了 50GB 数据,AOF 回放可能要几十分钟,RDB 几秒搞定
  • 主从复制:新从节点首次全量同步时,主节点会自动触发 RDB 快照传给从节点

[!QUESTION] 为什么 RDB 恢复比 AOF 快? 打个比方:RDB 就像拍了一张照片,加载时直接"看照片"还原场景;AOF 则像记了一本流水账("先加了张三,再删了李四,又改了王五……"),恢复时需要从头到尾把账本念一遍——数据量越大,"念账本"的时间就越长。

触发机制

手动触发

# 当前线程执行,阻塞主线程 ❌ 生产环境禁用!
SAVE

# 主进程 fork 子进程在后台完成(✅ 推荐)
BGSAVE

# 查看上次 BGSAVE 成功的时间戳
LASTSAVE
命令 行为 适用场景 风险
SAVE 同步阻塞,直到快照完成 紧急调试,或确认实例无流量时 主线程完全卡死——所有客户端请求排队等待
BGSAVE fork 子进程异步完成 生产环境日常备份 fork 瞬间有极短暂的阻塞(通常毫秒级)

[!QUESTION] 为什么 SAVE 危险但 Redis 还要提供它? 因为 SAVE 可以在 BGSAVE 正在执行时 强制同步保存(BGSAVE 期间再次 BGSAVE 会被拒绝)。这是一个极端场景的"保底"手段。

自动触发——条件持久化

通过 redis.conf 配置多条 save 规则,Redis 用一个**"脏键计数器"(dirty counter)** 来追踪:

save 900 1     # 900 秒内至少有 1 个 key 被修改 → 触发快照
save 300 10    # 300 秒内至少有 10 个 key 被修改
save 60 10000  # 60 秒内至少有 10000 个 key 被修改

[!INFO] 底层是怎么工作的? Redis 内部维护两个计数器:

  1. dirty 计数器:自上次 BGSAVE 成功以来,总共被修改的 key 数量(每次写操作 +1)
  2. lastsave 时间戳:上次成功完成 BGSAVE 的 Unix 时间戳

每隔 100ms(serverCron 定时任务),Redis 会检查:当前时间 - lastsave ≥ 阈值时间 && dirty ≥ 阈值次数,两个条件同时满足才会触发 BGSAVE。

所以 save 900 1 的意思是:"距离上次快照超过 900 秒并且期间有至少 1 个 key 被修改过"。如果 900 秒内没有任何写操作,即使规则匹配了也不会触发——因为没有新数据需要保存。

[!QUESTION] 为什么要设三档而不是一档? 这是一个渐进式频率设计:

  • 低活跃度(900s/1key):写入很少时,15 分钟存一次就够了——即使丢了 15 分钟的数据,也几乎没什么损失
  • 中活跃度(300s/10key):中等写入压力时,5 分钟存一次,平衡了 I/O 开销和数据安全
  • 高活跃度(60s/10000key):大量写入时,1 分钟存一次——虽然 fork 更频繁了,但此时丢 1 分钟的数据损失也更大

本质上是"数据越重要、变更越频繁,保存就越勤"的策略。

# 运行时动态修改(覆盖所有规则)
CONFIG SET save "900 1 300 10 60 10000"

# 临时关闭自动快照(谨慎!相当于禁用 RDB 自动触发)
CONFIG SET save ""

[!WARNING] CONFIG SET 不持久化 CONFIG SET 仅在内存中生效,Redis 重启后会恢复 redis.conf 的配置。若要永久生效,必须修改 redis.conf 并执行 CONFIG REWRITE 或手动重启。

其他自动触发场景

除了 save 规则外,以下场景也会自动触发 RDB:

场景 说明 为什么需要?
正常关闭 执行 SHUTDOWN 时自动触发一次 BGSAVE,保证关闭前数据落盘 优雅关闭 ≠ 数据丢失
主从全量同步 新从节点首次连接主节点时,主节点自动触发 BGSAVE 并将快照传给从节点 从节点需要一份完整的数据副本
AOF 重写 开启混合持久化后,BGREWRITEAOF 会先写 RDB 快照作为基线 后面"混合持久化"章节详解

[!TIP] Redis 如何避免"撞车"? Redis 同一时刻只会有一个子进程在做持久化。如果 BGSAVE 正在执行,此时再触发 SAVE/BGSAVE:

  • BGSAVE → 直接返回错误 ERR Background save already in progress
  • SAVE → 会等待 BGSAVE 完成后再执行

这个设计避免了多个子进程争抢 I/O 资源。

RDB 文件结构

可以把 .rdb 文件想象成一个快递包裹:有快递单号(Header)、多个包裹(DB 里的数据)、包裹拆完的标记(EOF)、以及签收校验码(Footer)。

flowchart TD
    subgraph header["1 HEADER 文件头"]
        A["Magic: REDIS07 + Version"]
        B["Auxiliary Fields: redis-ver, ctime, used-mem"]
        C["DB Selector: FE 00(选择 DB 0)"]
        A --> B --> C
    end

    subgraph data["2 DATA 数据段(每个非空 DB 重复一次)"]
        D["Key Type: 1 byte(String=0, List=1, Set=2 ...)"]
        E["Expire Info: 可选, TTL 时间戳"]
        F["Encoded Key + Value: 直接序列化底层数据结构"]
        D --> E --> F
        F -.-> G["... 重复 N 个 Key-Value 对 ..."]
    end

    subgraph footer["3 FOOTER 文件尾"]
        H["EOF Marker: 0xFF(数据结束)"]
        I["CRC64 Checksum: 8 bytes(完整性校验)"]
        H --> I
    end

    header --> data --> footer

各段含义详解

1️⃣ Header(文件头)

  • Magic 字符串:以 REDIS 开头 + 4 字节版本号(如 REDIS0009),用于标识"这是一个 RDB 文件"
  • 辅助字段(Auxiliary Fields):记录 Redis 版本、创建时间、内存占用等元信息——不是数据本身,只是"快递单信息"
  • DB Selector:FE + DB 编号,告诉你"接下来的数据属于哪个 DB"(默认只有 DB 0 有数据,所以通常只出现一次)

2️⃣ Data(数据段)

每个 key-value 对的存储格式:

字段 大小 说明
Key Type 1 byte 值的类型标记:String=0, List=1, Set=2, ZSet=3, Hash=4 …
Expire Time 0 或 8 bytes 如果 key 设置了过期时间,会附带一个毫秒级时间戳
Key 变长 key 名(字符串编码)
Value 变长 直接序列化底层数据结构(ziplist、intset、skiplist 等),这是 RDB 文件紧凑的关键

3️⃣ Footer(文件尾)

  • EOF 标记:0xFF,一个字节,宣告"数据到这里结束了"
  • CRC64 校验和:8 字节,Redis 加载文件时用它校验完整性——如果校验失败,说明文件损坏,加载直接报错

[!QUESTION] 为什么 RDB 文件比 AOF 小很多? 核心在于存储方式不同。举个例子:

假设你用 HSET user:1 name "Alice" age 25 city "Beijing" 存了一个 Hash:

  • AOF 记录的是:这条命令字符串本身 → *8\r\n$5\r\nHSET\r\n$6\r\nuser:1\r\n$4\r\nname\r\n...\ 约 120+ 字节
  • RDB 记录的是:Hash 类型标记 + ziplist 编码的紧凑字节流 → 约 30-40 字节

差距来自:RDB 不记录"怎么做的",只记录"结果是什么"——就像一张照片远比描述照片的文字更紧凑。

关键配置参数

# ---- RDB 核心参数 ----
dbfilename dump.rdb              # 快照文件名(建议保留默认)
dir /var/lib/redis               # 工作目录——RDB/AOF 文件都存放在这里
rdbcompression yes               # 是否使用 LZF 压缩字符串
rdbchecksum yes                  # 是否在文件末尾写入 CRC64 校验
rdb-save-incremental-fsync yes   # 写入磁盘时是否增量 fsync
rdb-del-sync-files no            # 无盘复制时,是否删除用于同步的临时 RDB(Redis 7+)

参数逐个解释

参数 推荐值 为什么?
dbfilename dump.rdb 保持默认即可。如果一台机器跑多个 Redis 实例,建议用端口号区分,如 dump-6379.rdb
dir /var/lib/redis 快照文件存放目录。必须确保该目录有足够磁盘空间,且 Redis 进程有写权限
rdbcompression yes 开启 LZF 压缩可减少 40%-60% 的磁盘占用,代价是写入时多消耗一点 CPU。绝大多数场景推荐开启
rdbchecksum yes 开启后在文件末尾写入 CRC64 校验码,加载时会验证完整性。关闭可略微提升加载速度,但不值得冒险
rdb-save-incremental-fsync yes 开启后,子进程每写入 32MB 就执行一次 fsync,避免一次性刷盘造成 I/O 尖峰。对 SSD 尤其友好

[!QUESTION] rdbcompression 关闭能提升多少性能? 压缩的 CPU 开销其实很小(LZF 是轻量压缩算法),瓶颈通常在磁盘 I/O 而非 CPU。关闭压缩后文件变大 → 写入时间更长 → 可能反而更慢。所以除非你有明确的 CPU profiling 数据证明压缩是瓶颈,否则不要关。

Fork 过程详解

BGSAVE 的核心操作是 fork()——这是 Linux 的系统调用,能以极低的成本创建一份进程副本。整个流程如下:

sequenceDiagram
    participant Client as 客户端
    participant Main as 主进程
    participant Child as 子进程
    participant Disk as 磁盘

    Client->>Main: 发送 BGSAVE 命令
    Main->>Main: 创建子进程(fork)
    Note over Main: fork 返回 0(子进程视角)<br/>fork 返回 pid(主进程视角)
    Main->>Client: 返回 OK(立即响应)
    par 主进程继续服务
        Main->>Main: 正常处理读写请求
    and 子进程执行快照
        Child->>Child: 遍历所有 key-value
        Child->>Disk: 序列化写入 dump.rdb.tmp
        Note over Child,Disk: 写入过程中如果主进程修改了数据<br/>内核通过 COW 机制保护子进程视图
        Child->>Main: 通知:快照完成
    end
    Main->>Disk: rename dump.rdb.tmp -> dump.rdb(原子替换)
    Main->>Main: 更新 lastsave 时间戳, 重置 dirty 计数器

[!TIP] 为什么 fork 这么快? fork() 并不会真的复制整个内存。Linux 使用**"写时复制"(Copy-On-Write, COW)——fork 之后,父子进程共享同一份物理内存页**,只在某一方写入时才真正拷贝那一页。所以 fork 一个 10GB 的 Redis 实例,实际瞬间开销只是创建页表(通常几十 MB),远小于 10GB。

深入理解 COW(Copy-On-Write)

[!INFO] 图书馆类比 想象一个图书馆(物理内存),里面有很多书(内存页)。

  • fork 之前:只有主进程一个人在看书
  • fork 之后:子进程也进了图书馆,两人看同一本书,不需要额外复印——这就是"共享"
  • 主进程想在书上做笔记(写入):图书馆员说"不行,这本书要保护",于是复印了一份给主进程,子进程继续看原版——这就是"写时复制"
  • 如果主进程不写:从头到尾只有那一本书,零额外开销
flowchart TD
    F["Fork 完成"] --> S["父子进程共享<br/>所有物理内存页"]
    S --> W{"主进程收到<br/>写请求?"}
    W -->|"否"| R["子进程继续读取原页<br/>(零拷贝,极快)"]
    W -->|"是"| C["内核复制该内存页<br/>(Copy-On-Write)"]
    C --> N["主进程写入副本页<br/>子进程仍读原页"]
    R & N --> D["子进程完成序列化"]
    D --> DONE["RDB 文件生成完成"]

[!QUESTION] BGSAVE 期间 Redis 内存会翻倍吗? 不会翻倍,但最坏情况接近翻倍。

fork 本身不复制任何内存页。只有当主进程实际写入某一页时,那一页才会被 COW 拷贝。两种极端情况:

场景 额外内存开销
BGSAVE 期间主进程几乎不写入 ≈ 0(只共享,不拷贝)
BGSAVE 期间主进程全量写入 ≈ 接近翻倍(每一页都被拷贝)
实际生产环境 通常 10%-30%(只有被修改的 key 对应的页才会 COW)

[!WARNING] fork 失败的常见原因 fork 需要内核分配页表空间,如果系统内存不足会失败。关键运维参数:

  • vm.overcommit_memory = 1:告诉内核"允许过度提交",这是 Redis 官方推荐的 Linux 设置
  • vm.overcommit_ratio:默认 50,配合 overcommit_memory=2 使用

如果你看到 Can't save in background: fork: Cannot allocate memory,大概率是这个参数没设置对。

TTL / 过期键处理

[!QUESTION] RDB 快照会保存已过期的 key 吗? 不会。 这是一个容易误解的点——很多人以为快照是"拍照片",会原封不动地保存内存里所有东西。但实际上,Redis 在"拍照"之前会先"打扫房间"。

具体流程:

  1. BGSAVE 触发时,主线程先执行一次主动过期扫描,把所有已超时的 key 从内存中删除
  2. 删除完成后,才 fork 子进程
  3. 子进程遍历剩余的 key → 序列化写入 .rdb 文件
  4. 结论:.rdb 文件中只有有效数据,不包含过期键
flowchart LR
    A["BGSAVE 触发"] --> B["主线程: 主动过期扫描<br/>清理所有已超时 Key"]
    B --> C["Fork 子进程"]
    C --> D["子进程: 遍历有效数据<br/>序列化写入 .rdb"]
    D --> E["RDB 文件中无过期键"]
    style E fill:#c4e8b0

[!NOTE] 一个细节:RDB 加载时也会二次检查 即使某个 key 在快照时还没过期,但等到恢复加载时已经过期了——Redis 在加载 RDB 文件时会再次检查 TTL,过期的 key 不会被加载到内存。这保证了无论什么时候恢复,数据都是"新鲜"的。

恢复流程

Redis 启动时会自动检测 dir 目录下的 .rdb 文件并加载——你不需要手动执行任何"恢复命令"。

场景一:正常重启(最常见)

# 直接重启即可,Redis 自动加载 dump.rdb
redis-server /path/to/redis.conf

Redis 启动日志中你会看到类似:

* DB loaded from disk: 0.052 seconds    # ← 52ms 加载完成

场景二:从备份恢复(灾难恢复)

当服务器故障需要从备份 .rdb 恢复时:

# 1. 停止当前 Redis(如果还在运行)
redis-cli SHUTDOWN NOSAVE    # NOSAVE = 不再生成新快照,直接关闭

# 2. 把备份的 .rdb 文件放到 Redis 工作目录
cp /backup/dump.rdb /var/lib/redis/dump.rdb

# 3. 启动 Redis,它会自动加载这个 .rdb
redis-server /path/to/redis.conf

# 4. 验证数据恢复
redis-cli DBSIZE            # 检查 key 总数
redis-cli INFO keyspace     # 查看各 DB 的 key 数量和过期 key 数量
redis-cli GET some_known_key # 抽样验证已知 key 是否存在

场景三:迁移数据到新实例

# 在旧实例上手动触发一次快照
redis-cli BGSAVE

# 等待完成
redis-cli LASTSAVE          # 观察时间戳变化

# 复制 .rdb 到新服务器
scp /var/lib/redis/dump.rdb user@new-server:/var/lib/redis/

# 在新服务器上启动 Redis(自动加载)
ssh user@new-server "redis-server /path/to/redis.conf"

[!WARNING] 恢复时的常见坑

  1. 文件权限:确保 Redis 进程对 dir 目录有读写权限(启动时需要读取,运行时需要写入新快照)
  2. 磁盘空间:.rdb 文件恢复时需要临时解压到内存,确保服务器可用内存 ≥ RDB 文件大小
  3. 同时存在 AOF 和 RDB:如果 dir 下同时有 dump.rdb 和 appendonly.aof,Redis 优先加载 AOF(因为 AOF 数据通常更新)。如果你确实想用 RDB 恢复,需要先移走 AOF 文件
  4. 版本兼容:低版本 Redis 不能加载高版本生成的 RDB 文件(向后不兼容)

RDB vs AOF 对比

维度 RDB AOF 为什么?
数据安全性 ⚠️ 可能丢失两次快照间的数据 ✅ 最多丢 1 秒数据(everysec 策略) RDB 是"定期拍照",AOF 是"实时写日记"
恢复速度 ⚡ 极快(直接加载二进制文件) 🐢 较慢(逐条回放命令) 读一本 100 页的书 vs 回放 100 万条操作日志
文件大小 ✅ 小(压缩后的二进制) ❌ 大(文本命令持续追加) 照片 vs 逐帧视频——信息密度不同
CPU 开销 低(偶尔 fork) 高(每条写命令都要追加) 定期批量 vs 持续实时的天然差异
对写入性能影响 极小(fork 子进程异步完成) 有影响(每次写都要 append) BGSAVE 不阻塞主线程,AOF fsync 可能短暂阻塞
适用场景 备份、灾难恢复、主从同步 对数据安全要求高的在线服务 各取所长

[!QUESTION] 生产环境怎么选? 答案是:不要二选一,两个都开。 Redis 4.0+ 引入的混合持久化(下文详解)完美解决了这个矛盾——RDB 保证恢复速度,AOF 保证数据安全。

Redis 混合持久化(推荐)

为什么需要混合持久化?

回顾一下两者的痛点:

方案 优点 痛点
RDB 恢复快、文件小 两次快照间的数据可能丢失
AOF 数据几乎不丢 恢复慢、文件大

[!QUESTION] 能不能把两者结合起来——用 RDB 加速恢复 + 用 AOF 保证数据安全? 可以!Redis 4.0 引入了混合持久化(Hybrid Persistence),正是为了解决这个矛盾。

原理:AOF 文件 = RDB 快照 + 增量日志

开启混合持久化后,AOF 重写时不再只写命令日志,而是:

flowchart LR
    A["AOF 重写触发"] --> B["先写入一份 RDB 快照<br/>(覆盖重写时刻的全量数据)"]
    B --> C["再追加重写期间的增量命令"]
    C --> D["最终 AOF 文件"]

    style D fill:#c4e8b0

也就是说,生成的 AOF 文件结构变成了:

┌──────────────────────────────────────┐
│  RDB 二进制快照(全量数据基线)          │  ← 启动时直接加载,秒级完成
├──────────────────────────────────────┤
│  增量 AOF 命令(快照之后的写操作)       │  ← 逐条回放,保证数据不丢
└──────────────────────────────────────┘

[!INFO] 用"写日记"来类比

  • 纯 RDB = 定期拍照(恢复快,但照片之间的事不知道)
  • 纯 AOF = 每天写日记(信息完整,但要从头读到尾才能恢复全部记忆)
  • 混合持久化 = 定期拍照 + 每天写日记。恢复时先看最近的照片(RDB 部分),再读照片之后的日记(AOF 部分)——既快又完整

如何开启

# redis.conf
aof-use-rdb-preamble yes      # Redis 4.0+, 默认就是 yes
appendonly yes                 # 必须开启 AOF

恢复速度对比

flowchart LR
    T1["传统 AOF 恢复<br/>回放数百万条命令"] -->|"O(N) 慢"| R1["耗时: 分钟级别"]

    H1["RDB 快照加载<br/>秒级还原全量数据"] -->|"O(1) 快"| R2["耗时: 秒级"]
    H2["回放少量增量 AOF<br/>仅重写后的命令"] -->|"极少"| R2

    style R1 fill:#f9d0c4
    style R2 fill:#c4e8b0

[!TIP] 混合持久化几乎是"无脑开启"的配置

  • 恢复速度 ≈ RDB(因为大部分数据在 RDB 部分,AOF 增量部分很少)
  • 数据安全 ≈ AOF(增量日志保证不丢数据)
  • 开销 = AOF rewrite 的 fork 开销(和纯 AOF 一样)

Redis 5.0+ 已默认开启,建议检查你的配置确认一下。

最佳实践

[!SUMMARY] 核心原则:RDB 是备份手段,不是实时数据保障 不要把 RDB 当成"实时安全网"——它的定位是定期快照 + 灾难恢复兜底。实时数据安全交给 AOF。

  1. 不要只依赖 RDB:生产环境推荐 AOF + 混合持久化,AOF 保证数据安全,RDB 加速恢复
  2. 合理设置 save 频率:默认三档适合大部分场景。写入密集型可适当提高频率,但要注意:
    • 频率越高 → fork 越频繁 → CPU 和内存压力越大
    • 经验法则:rdb_last_bgsave_time_sec 超过 1 秒就需要关注
  3. 备份策略(自动化):
#!/bin/bash
# redis-backup.sh — 每日定时备份脚本示例
REDIS_CLI="redis-cli"
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)

# 1. 触发一次快照
$REDIS_CLI BGSAVE

# 2. 等待完成(轮询 lastsave)
LAST=$($REDIS_CLI LASTSAVE)
while [ "$($REDIS_CLI LASTSAVE)" == "$LAST" ]; do sleep 1; done

# 3. 拷贝并压缩
cp /var/lib/redis/dump.rdb "$BACKUP_DIR/dump-$DATE.rdb"
gzip "$BACKUP_DIR/dump-$DATE.rdb"

# 4. 保留最近 7 天的备份,删除更早的
find "$BACKUP_DIR" -name "dump-*.rdb.gz" -mtime +7 -delete

echo "Backup completed: dump-$DATE.rdb.gz"
  1. 监控关键指标:通过 INFO persistence 关注以下字段:
指标 含义 告警阈值建议
rdb_last_bgsave_status 上次 BGSAVE 是否成功 ≠ ok 立即告警
rdb_last_bgsave_time_sec 上次 BGSAVE 耗时 > 1s 关注,> 5s 告警
rdb_last_save_time 上次成功快照的时间戳 距今 > 1h 未触发则排查
rdb_changes_since_last_save 上次快照后的变更 key 数 持续增长说明 save 规则可能失效
  1. 磁盘选择:RDB 写入对 I/O 有要求,建议使用 SSD 并保持 rdb-save-incremental-fsync yes

[!WARNING] 大 Key 是 RDB 的天敌 一个 100MB 的 String key,序列化时子进程写入耗时剧增(单个 key 可能就要写几秒),同时 COW 也会产生大量页面复制。

排查方法:redis-cli --bigkeys 扫描大 key,发现后优先拆分。详见 hhs/Redis/11-运维与性能调优。

运维速查手册

# ---- 查看 RDB 状态 ----
INFO persistence
# 重点关注这些字段:
# rdb_last_bgsave_status: ok        ← 上次是否成功
# rdb_last_bgsave_time_sec: 2       ← 上次耗时几秒
# rdb_last_save_time: 1715000000    ← 上次成功时间戳(Unix)
# rdb_changes_since_last_save: 1234 ← 自上次快照后的变更 key 数

# ---- 查看快照文件 ----
ls -lh /var/lib/redis/dump.rdb
# -rw-rw---- 1 redis redis 1.2G May 22 03:00 dump.rdb

# ---- 手动触发一次快照并等待完成 ----
redis-cli BGSAVE
# 等待:轮询 LASTSAVE 直到时间戳变化
while [ "$(redis-cli LASTSAVE)" == "$OLD" ]; do sleep 0.5; done

# ---- 检查 RDB 文件是否完整(不启动 Redis 的情况下) ----
# Redis 自带工具,用于检查 .rdb 文件的完整性
redis-check-rdb /var/lib/redis/dump.rdb
# 输出 OK 则文件完整,否则会告诉你哪里损坏了

关联笔记