文章

Redis 持久化

RDB

默认情况下,Redis使用RDB持久化机制,它保存内存数据库快照到dump.rdb的二进制文件中。

在redis.conf中配置RDB持久化触发策略:

# 举例说明,可以配置多个save策略,注释掉所有save策略相当于关闭RDB持久化
save 60 1000  # 表示60秒内有不少于1000个键被修改时触发RDB持久化

也可以手动触发RDB持久化:进入Redis客户端执行save或者bgsave命令

save

bgsave

IO类型

同步

异步

是否阻塞客户端命令

否(fork子进程时会短暂堵塞)

优点

不会消耗额外内存

基本不阻塞客户端命令

缺点

会阻塞客户端命令

需要fork子进程,会消耗额外内存

bgsave的写时复制机制

写时复制技术(Copy-On-Write,COW)将复制操作推迟到写操作真正发生的时候,Redis借助操作系统的写时复制技术,做到了在进行RDB持久化生成快照的时候,也可以正常处理写请求。

bgsave的子进程是由主进程fork生成的,可以共享主进程的所有内存数据。bgsave主进程运行后,会读取主进程的内存数据并持久化到RDB文件中。此时,如果主进程对这些数据执行写操作,即将修改的数据会被复制一份,子进程读取副本数据写入RDB文件,而主进程正常修改原来的数据。

AOF(Append Only File)

每次全量保存RDB快照耗时比较长,因此RDB持久化触发间隔不能设置太小,在这个比较长的持久化间隔中,如果Redis宕机,会丢失很多数据。

因此Redis提供了另外一种持久化机制,即AOF,它会将执行的每一条修改命令都记录到{appendfilename} 文件中(appendfilename默认为appendonly.aof)

考虑到效率,实际会先写入os cache,每隔一段时间fsync到磁盘

AOF相关配置

appendonly yes  # 打开AOF持久化

# 执行fsync的默认策略为everysec
appendfsync always  # 每次有新的命令追加到AOF文件时,就执行一次fsync(持久化非常慢,但是非常安全)
appendfsync everysec  # 每秒执行一次fsync(持久化足够快,最多丢失1秒的数据)【默认】
appendfsync no  # 交给操作系统判断什么时候执行fsync(持久化非常快,但是非常不安全)

AOF文件一览

set Jerry 666 为例:

*3  # 接下来的这条命令由3个部分组成
$3  # 命令的第1个部分有3个字符
set
$5  # 命令的第2个部分有5个字符
Jerry
$3  # 命令的第3个部分有3个字符
666

AOF重写

时间长了,AOF文件中会有很多冗余的命令,因此AOF会定期根据内存最新数据重新生成AOF文件。

会fork一个子进程去执行AOF重写操作

以id为1的文章点赞数为例:

incr article:likes:1
incr article:likes:1
incr article:likes:1
incr article:likes:1
incr article:likes:1

这里5个点赞等价于 set article:likes:1 5,浪费了很多空间,可以重写为:

*3
$3
set
$15
article:likes:1
$1
5

AOF重写相关配置:

auto-aof-rewrite-min-size 64mb  # AOF文件自动重写需要达到的大小
auto-aof-rewrite-percentage 100  # 上次重写后,下次重写需要AOF文件大小增长的百分比

RDB和AOF对比

RDB

AOF

持久化文件大小

重建内存的速度

数据安全性

宕机时丢数据较多

宕机时丢数据较少

由于宕机时AOF丢数据较少,当Redis重启时,会优先使用AOF文件重建内存数据,其次使用RDB文件。

混合持久化

Redis 4版本开始,吸取RDB和AOF两种持久化方式的优点,新增了一个持久化方式:混合持久化。

通过 aof-use-rdb-preamble yes 配置开启混合持久化,本质上混合持久化是对AOF的优化,因此也必须开启AOF。

如果开启了混合持久化,Redis在重写AOF时,会将重写这一时刻之前的内存数据保存为RDB快照,而重写之后新增的命令以AOF的方式追加写入。

使用混合持久化之后,Redis重建内存数据时,会先使用RDB数据重建大部分数据,再使用AOF数据重建最后的小部分数据,重建速度得以大大提升。

在Redis 7版本之前,RDB快照数据和增量AOF数据都保存在{appendfilename}文件中(appendfilename默认为appendonly.aof),从7版本开始,RDB快照数据保存到 {appendfilename}.{序号}.base.rdb 中, 增量AOF数据保存到{appendfilename}.{序号}.incr.aof中

Redis持久化数据备份策略

例如,可以使用crontab定时脚本:

  1. 每小时复制一份RDB或AOF文件到一个指定目录,仅保留48小时的备份

  2. 每一天复制一份RDB或AOF文件到一个指定目录,仅保留30天的备份

  3. 每天晚上将当前机器的备份数据复制到其他机器上

License:  CC BY 4.0