redis持久化机制及其日志

RDB机制

RDB是某一时刻全量数据快照,把内存数据一次性写入 .rdb 二进制文件,保存到磁盘

触发方式
  • 自动触发
    Redis通过配置文件中 save 参数定义了 RDB 的自动保存条件。以下是默认配置的示例:

    save 900 1    # 如果900秒内至少有1个键发生变化,则保存快照
    save 300 10   # 如果300秒内至少有10个键发生变化,则保存快照
    save 60 10000 # 如果60秒内至少有10000个键发生变化,则保存快照
    
  • 手动触发

    • save : 同步执行 , 阻塞主线程, 生产禁用
    • bgsave: 后台异步, fork子进程进行, 占用部分内存/cpu资源
优缺点分析
  • 优点:
    • 文件小 , 恢复速度快,适合定期备份,容灾恢复
  • 缺点:
    • 丢失最后一次快照后的数据 , 不适合实时性要求高场景

AOF机制

AOF 记录每一条写命令(类似 MySQL binlog),以文本形式追加到 appendonly.aof

但是如果Redis刚刚执行完一个写命令,还没来得及写AOF文件就宕机了,那么这个命令和相应的数据就会丢失了。但是他也比RDB要更加靠谱一些。

配置命令
appendonly yes          # 开启 AOF
appendfilename appendonly.aof # AOF持久化文件名
appendfsync everysec     # 刷盘策略
写回策略
  • Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
  • Everysec,每秒写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;
  • No,操作系统控制的写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。

效率:NO>EverySec>Always

可靠性:Always > EverySec > NO

AOF重写

随着命令写入AOF文件,越来越大,因此提供了AOF重写压缩文件

配置:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb 

AOF 比上次重写后增大 100% 且大于 64MB 时自动重写。

优缺点分析
  • 优点:
    • 数据安全性,实时性高 , Everysec策略最多丢失1秒
    • 日志追加为顺序IO,性能高
  • 缺点:
    • 恢复速度慢
    • 高写入环境IO压力大
    • 文件大

RDB和AOF对比

特性 RDB AOF
数据可靠性 可能会丢失最后一次快照之后的数据 保证最后一次写操作之前的数据不会丢失
性能 读写性能较高,适合做数据恢复 写性能较高,适合做数据存档
存储空间占用 快照文件较小,占用空间较少 AOF文件较大,占用空间较多
恢复时间 从快照文件中恢复数据较快 从AOF文件中恢复数据较慢

混合使用

AOF 文件前半部分是 RDB 格式全量数据,后半部分是 AOF 格式增量命令

配置
aof-use-rdb-preamble yes

结合AOF和RDB的优点, 恢复速度快 , 数据实时性高(丢失少)

持久化是否可以确保数据不丢失?

不行

即使是在always策略下,也不能保证100%不丢失数据:

  1. 磁盘和系统故障:如果在写入操作和同步到磁盘之间发生硬件故障或系统崩溃,可能会丢失最近的写操作。

  2. 操作系统缓冲区:即使Redis请求立即将数据同步到磁盘,操作系统的I/O缓冲区可能会导致实际写入磁盘的操作延迟发生。如果在写入缓冲区之后,没写磁盘前,机器挂了,那么数据就丢了。

    操作系统缓冲区,通常指的是操作系统用于管理数据输入输出(I/O)的一种内存区域。当程序进行文件写入操作时,数据通常首先被写入到这个缓冲区,而不是直接写入到硬盘。

  3. 磁盘写入延迟:磁盘的写入并非实时完成,特别是在涉及到机械硬盘时,写入延迟主要由磁盘旋转速度(RPM)和寻道时间决定。如果在这这个延迟过程中,机器挂了,那么数据也就丢了。

持久化配置最佳实践

#=========================================
# RDB 快照配置(用于冷备 + 快速恢复)
#=========================================
save 3600 1
save 300 100
save 60 10000

stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis

#=========================================
# AOF 配置(保证数据安全,核心推荐)
#=========================================
appendonly yes                  # 开启 AOF
appendfilename "appendonly.aof"

# 刷盘策略:生产标准方案
appendfsync everysec

# 重写时不 fsync,降低磁盘压力,避免阻塞
no-appendfsync-on-rewrite yes

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

#=========================================
# 混合持久化(Redis 4.0+ 强烈推荐)
#=========================================
aof-use-rdb-preamble yes        # 开启 RDB+AOF 混合模式

#=========================================
# 高级优化(减少 fork 阻塞 & 提升稳定性)
#=========================================
repl-diskless-sync yes
repl-diskless-sync-delay 5
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
replica-lazy-flush yes

# 降低 fork 内存拷贝压力
oom-score-adj -1000
maxmemory 16G  # 根据实际机器内存调整

混合持久化日志解析

在redis开启混合持久化后 , 执行以下命令作为测试数据

> SADD test:a 111
1
> SADD test:a 23213
1
> SADD test:b 1231231
1
> SADD test:c kkdaod
1

/var/lib/redis/appendonlydir 中执行

[root@VM-0-4-opencloudos appendonlydir]# ls
appendonly.aof.1.base.rdb  appendonly.aof.1.incr.aof  appendonly.aof.manifest
[root@VM-0-4-opencloudos appendonlydir]# cat appendonly.aof.manifest  
file appendonly.aof.1.base.rdb seq 1 type b
file appendonly.aof.1.incr.aof seq 1 type i
[root@VM-0-4-opencloudos appendonlydir]# cat appendonly.aof.1.incr.aof 
*2
$6
SELECT
$1
1
*3
$4
sadd
$6
test:a
$5
23213
*3
$4
sadd
$6
test:b
$7
1231231
*3
$4
sadd
$6
test:c
$6
kkdaod
[root@VM-0-4-opencloudos appendonlydir]# redis-check-rdb appendonly.aof.1.base.rdb
[offset 0] Checking RDB file appendonly.aof.1.base.rdb
[offset 26] AUX FIELD redis-ver = '7.2.7'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1775113532'
[offset 67] AUX FIELD used-mem = '866752'
[offset 79] AUX FIELD aof-base = '1'
[offset 88] Checksum OK
[offset 88] \o/ RDB looks OK! \o/
[info] 0 keys read
[info] 0 expires
[info] 0 already expired

其中三个文件appendonly.aof.1.base.rdb/appendonly.aof.1.incr.aof/appendonly.aof.manifest

base : 基础快照RDB的二进制快照文件

incr: AOF的新增命令

manifest: 清单文件,记录有哪些文件

appendonly.aof.1.incr.aof 的从内容则可以看出是我们执行的命令

*3
$4
sadd
$6
test:c
$6
kkdaod

==> SADD test:c kkdaod

*2
$6
SELECT
$1
1

==>  select 1 #使用数据库1

因为RDB的快照为二进制文件,使用redis命令redis-check-rdb查看

其结果通过ai解释

# 执行命令:使用Redis自带的redis-check-rdb工具,检查指定的RDB文件是否完整、合法
[root@VM-0-4-opencloudos appendonlydir]# redis-check-rdb appendonly.aof.1.base.rdb

# 日志:从文件偏移量0开始,检查目标RDB文件(该文件是Redis AOF持久化的基础RDB文件)
[offset 0] Checking RDB file appendonly.aof.1.base.rdb

# 日志:偏移量26处,读取到辅助字段:Redis服务版本为7.2.7
[offset 26] AUX FIELD redis-ver = '7.2.7'

# 日志:偏移量40处,读取到辅助字段:Redis运行在64位系统
[offset 40] AUX FIELD redis-bits = '64'

# 日志:偏移量52处,读取到辅助字段:RDB文件创建时间戳(1775113532)
[offset 52] AUX FIELD ctime = '1775113532'

# 日志:偏移量67处,读取到辅助字段:RDB文件生成时Redis占用内存大小(866752字节)
[offset 67] AUX FIELD used-mem = '866752'

# 日志:偏移量79处,读取到辅助字段:标记该文件是AOF持久化的基础RDB文件(1=是)
[offset 79] AUX FIELD aof-base = '1'

# 日志:偏移量88处,文件校验和验证通过(文件无损坏、无篡改)
[offset 88] Checksum OK

# 日志:偏移量88处,RDB文件检查完成,文件状态健康
[offset 88] \o/ RDB looks OK! \o/

# 日志:统计信息:本次检查读取到0个键值对
[info] 0 keys read

# 日志:统计信息:0个键设置了过期时间
[info] 0 expires

# 日志:统计信息:0个键已经过期
[info] 0 already expired

可以看出我们刚才执行的命令只是被添加到AOF追加文件中 , 接下来我们执行BGREWRITEAOF命令来重写AOF文件

[root@VM-0-4-opencloudos appendonlydir]# ls
appendonly.aof.2.base.rdb  appendonly.aof.2.incr.aof  appendonly.aof.manifest
[root@VM-0-4-opencloudos appendonlydir]# cat appendonly.aof.manifest 
file appendonly.aof.2.base.rdb seq 2 type b
file appendonly.aof.2.incr.aof seq 2 type i
[root@VM-0-4-opencloudos appendonlydir]# cat appendonly.aof.2.incr.aof 
[root@VM-0-4-opencloudos appendonlydir]# redis-check-rdb appendonly.aof.2.base.rdb 
[offset 0] Checking RDB file appendonly.aof.2.base.rdb
[offset 26] AUX FIELD redis-ver = '7.2.7'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1775117162'
[offset 67] AUX FIELD used-mem = '1162592'
[offset 79] AUX FIELD aof-base = '1'
[offset 81] Selecting DB ID 1
[offset 157] Checksum OK
[offset 157] \o/ RDB looks OK! \o/
[info] 3 keys read
[info] 0 expires
[info] 0 already expired

重新执行一遍命令,可以看出看到AOF文件为空 , 而RDB二进制文件添加了3个键值对 , 这就是一次持久化中,redis持久化日志的变化

posted @ 2026-04-02 17:01  Lwf663  阅读(1)  评论(0)    收藏  举报