Redis 持久化浅谈

本文详细介绍了Redis的持久化机制,包括RDB快照、AOF(Append-only file)以及RDB+AOF混合持久化。RDB在指定时间间隔生成内存快照,适合全量备份,但可能丢失部分数据;AOF记录每次修改操作,提供更高的数据安全性,但恢复速度较慢。混合持久化结合两者优点,提高数据恢复效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址 👉 欢迎访问我的个人博客 👈

Redis 版本:6.0.3

官方文档

1. Redis 持久化

Redis 持久化可以分为三种:

  • RDB 快照(SnapShot)
  • AOF(Append-only file)
  • 混合持久化(RDB + AOF)

2. RDB

默认情况下,Redis 的内存快照保存在 dump.rdb 的二进制文件中。该文件默认在 redis 安装目录下,当 rdb 文件存在时,redis 启动会先读取rdb文件并恢复数据。

R5S5ym.png

设置 Redis 开启RDB快照有三种方法:

  1. save:修改 redis.conf 文件,添加 save 命令,格式 save 时间(秒) 执行命令次数。例如 save 60 1000 指在60秒超过1000个改动命令的话自动执行 rdb 快照功能。
# save <seconds> <changes>
#
# Redis will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.

# 关闭
save "" # 或者注释掉所有 save 配置即可

  1. bgsave:写时复制机制(COW)

    • 从redis主线程fork一个子线程,该子线程拥有主线程所有数据
    • 子线程将所有数据备份到新的rdb文件(备份过程中,主线程仍可执行命令,不会阻塞)
    • 新的rdb文件会覆盖旧的rdb文件

    注意:redis 执行命令是单线程的,但不代表redis就是单线程的,像bgsave的子线程和主线程。

在 redis 客户端手动执行 savebgsave 也可以生成rdb备份文件,新生成的 rdb文件会覆盖旧的。

注意:flushall清除命令会重置rdb文件

Save和Bgsave对比:

savebgsave
IO同步异步
是否阻塞主线程否(fork主线程时会有短暂阻塞)
复杂度O(n)O(n)
优点执行时用的是主线程,不会消耗额外内存不阻塞主线程
缺点阻塞主线程fork主线程时会消耗内存

RDB持久化的优缺点:

优点:

  • 相比于AOF,数据量较大时,rdb文件更适合作为备份文件,因为其内部数据采用二进制形式存储,恢复数据时会更快更方便

缺点:

  • 有几率丢失部分数据,因为SnapShot是固定时间间隔执行的,所以如果在下次Snapshot之前系统出现宕机或者其他问题的话,这段时间尚未备份到rdb的数据便会丢失,最新的rdb文件只会备份到上次Snapshot的数据。
  • 当数据量较大时,fork子线程会损耗更多性能

3. AOF

AOF是一种比RDB更灵活持久的备份策略,会将每一条**修改(例如 set lpush等等)**的指令记录到appendonly.aof文件中(RDB是满足条件才会记录)。redis7.0后该文件会被拆分为多个文件。

注意:AOF并不是每次有新命令就会缓存到磁盘文件中,而是先写入系统缓存每隔一段时间在 fsync 到磁盘

Redis 启动时会自动读取aof文件中的命令参数进行命令重写,也就是将每条命令都执行一次。

打开AOF备份策略:修改 redis.conf 文件,将appendonly改为 yes (默认为 no)

appendonly yes

可修备份文件名称:

appendfilename "appendonly.aof"

AOF的备份策略(多久才将数据 fsync 到磁盘文件中):

  • appendfsync always: 没有新命令便执行一次 fsync,速度最慢也最安全
  • appendfsync everysec:每秒 fsync 一次 (默认)
  • appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。

开启AOF后,每条修改命令都会备份,appendonly.aof 文件里存储的是每条命令的解析,例如执行两条命令

set test1 1
set test2 2

appendonly.aof的内容:

RCPXgS.png

解析:set test1 1

*3:指该命令由三部分组成(1-set 2-test1 3-1)
$3:代表执行的命令长度,例如 set 的长度是3
set:执行的命令
$5:key的长度,如 test1
test1:key
$1:value的长度,如 1
1:value

当AOF文件存储的数据量越来越大,到了一定的程度后会触发AOF Rewriting(重写)。redis 会在后台(fork 一个子线程,不会阻塞主线程)对 aof 文件进行重写,优化那些重复的命令,例如:对某一个key进行重复的增量更新

RC1Feo.png

其在aof文件中的命令如下:可见 incr test1 这个命令重复了四次,如果这个次数是 10000 次 、100000次或者更大呢?那么redis启动读取aof文件并执行命令时就会重复执行相同的命令导致损耗更多的性能。为了解决这个问题,redis引入了重写。

重写可以手动触发也可以自动触发:在控制台输入 bgrewriteaof 可以手动触发重写

bgrewriteaof

自动触发可配置频率:

1 # auto‐aof‐rewrite‐min‐size 64mb //aof文件到设定大小后自动触发重写
2 # auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再次触发重写

重写功能可以将这些命令进行优化,例如这里的四次 incr 可以直接优化为 set test1 4,这样 redis 无需执行多次的重复命令从而优化性能。

RC1aKS.png

重写后文件大小对比:

RC3d9Y.png

RC301X.png

重写后的文件内容:已经变成了 set test1 4

RC3VIh.png

注意:开启混合开发后,内容会变成二进制形式

AOF和RDB的对比:

RDBAOF
优先级高(RDB和AOF文件同时存在时,redis会优先选择aof)
体积
备份回复速度
数据安全性容易丢失由备份策略决定

4. RDB + AOF 混合持久化

redis4.0 后为了解决RDB容易丢失数据和AOF恢复速度慢的问题引入了混合持久化的概念。开启混合持久化需要将 aof-use-rdb-preamble改为 yes

RCemf1.png

开启混合持久化后,RDB无需指定开启,命令默认存储到AOF文件中,每当AOF进行重写时,在重写那一刻会同时进行RDB快照并将RDB快照内容和AOF重写后的内容写入一个新的aof文件中,然后覆盖旧的aof文件。这样redis重启后会先读取aof文件中的RDB内容然后再读取aof自身重写后的内容进行数据恢复从而实现数据恢复效率的提升。

重写后的aof文件内容,以上面的4次incr为例:

RCeUHm.png

其结构为:RDB内容在AOF内容前面,所以恢复数据时先恢复RDB快照内容的数据,再恢复AOF内容的数据。

RCefhT.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值