概述
大多数时候,我们使用Redis
都是作为缓存使用,数据都是保存在内存中,一旦Redis
退出/重启,原先服务器中的数据就丢失了,为了解决这个问题,Redis
提供了两种持久化机制:RDB
和AOF
,下面分别介绍这两种机制
RDB 持久化方案介绍
RDB
即 Redis Database
,是Redis
的默认持久化方案,该方案会定期的将Redis
中的数据写入到磁盘,生成一个当前时刻的快照文件,我们称其为RDB
文件。当Redis
服务意外重启时,会读取最新的RDB
文件,使用该文件恢复服务器中的数据
RDB 工作原理
Redis
服务端在接收到save
或bgsave
时,会触发快照,生成RDB
文件。以save
为例,当执行save
127.0.0.1:6379> save
OK
会在工作目录下生成dump.rdb
文件
$ ls -al
total 8
drwxr-xr-x@ 3 huangxy staff 96 3 7 18:00 .
drwxr-xr-x 4 huangxy staff 128 3 3 22:45 ..
-rw-r--r-- 1 huangxy staff 188 3 7 18:00 dump.rdb
bgsave
命令作用与save
命令相同,唯一的区别是bgsave
不会阻塞Redis
服务端进程。所以实际工作中常用bgsave
而不用save
命令。当执行bgsave
命令时,Redis
会执行以下步骤:
forks
一个子进程,用于持久化数据- 子进程开始将
Redis
中的数据写入到一个临时RDB
文件中 - 当子进程完成数据的写入操作后,使用当前的
RDB
文件替换之前旧的RDB
文件
该工作流程类似于
Copy-On-Write
机制
RDB 配置
RDB
文件默认保存在当前工作目录下的dump.rdb
文件中,可以在redis.conf
文件中配置文件的存放路径与文件名
# 配置 Redis 工作目录
dir ./
# 指定 RDB 文件名
dbfilename dump.rdb
除了手动执行bgsave
命令生成RDB
文件外,还可以在配置文件中设置save
的规则,当满足规则时,服务器会自动执行bgsave
操作
save 900 1
save 300 10
save 60 10000
save
命令的格式为:save <seconds> <changes>
,表示在seconds
秒内,至少有changes
次数据变化,就执行bgsave
命令
如save 900 1
表示当15分钟
内至少有1次
数据改变,就执行bgsave
,想要配置多个规则,可以多写几行save
配置,当满足其中一条规则,就会执行bgsave
命令
AOF 持久化方案介绍
与RDB
不同,AOF
持久化会把服务器执行的写命令追加到AOF
文件中。所以AOF
文件中存放的就是具体的写命令,比如执行set
操作
127.0.0.1:6379> set foo bar
OK
AOF
文件中的内容如下
*3
$3
set
$3
foo
$3
bar
熟悉
RESP
协议的应该知道,该文件内容表示的就是set foo bar
当服务重启时,会重放AOF
文件,执行AOF
文件中的命令对数据进行恢复
AOF 配置
Redis
默认不开启AOF
持久化,可以在配置文件中添加下面配置打开AOF
持久化功能
appendonly yes
开启AOF
持久化后,为确保服务性能,执行写命令的时候,不是立即将命令写入到AOF
文件中,而是先将命令写入到aof_buf
缓存中,当满足一定条件时,再将缓存刷新到AOF
文件中。对于aof_buf
的刷新时机,Redis
提供了下面三种策略
appendfsync always
:每个写命令同步写入到AOF
文件中,该策略数据安全性最高,但会对磁盘进行大量的写操作,Redis
处理命令的速度会受到磁盘性能的影响appendfsync everysec
: 每秒同步一次aof_buf
缓存到AOF
文件中,使用该策略,即使服务器宕机,也只会丢失 1s 内的数据appendfsync no
: 不指定aof_buf
文件的刷新时机,什么时候将aof_buf
缓存中的数据写入到AOF
文件中,由操作系统调度,该方案对Redis
性能影响比较小,但当服务器宕机,可能会丢失不定数量的数据,因为缓存何时刷新由操作系统调度,用户并不知情
appendfsync
的默认配置为everysec
,即每秒同步一次
appendfsync everysec
此外,AOF
文件保存路径与文件名同样可以配置,默认保存在工作路径下的appendonly.aof
中
# 配置 Redis 工作目录
dir ./
# 配置 AOF 文件名
appendfilename appendonly.aof
AOF 重写机制
随着命令不断写入AOF
文件中,AOF
文件会越来越大,这回造成使用该AOF
进行数据恢复的时间变长。为了解决这个问题,Redis
引入了AOF
重写机制,可以通过手动/自动触发AOF
重写,进而压缩AOF
文件的大小,使文件能够更快的被Redis
加载
重写后的文件为什么可以变小?具体原因有:
- 进程内已经超时的数据不再写入文件,比如过期 key
- 旧的
AOF
文件含有无效命令,比如Redis
前后执行了同一个key
的插入与删除操作,先执行插入set foo bar
,后执行删除操作del foo
,那么,在重写的时候,这两条命令就属于无效命令,重写的时候无需将这两条命令写入文件 - 多条命令可以合并为一条,节省空间。比如
lpush list a
、lpush list b
、lpush list c
这三条命令其实可以合并为lpush list a b c
这一条命令
AOF
重写可以手动/自动触发,手动触发直接使用bgrewriteaof
命令。自动触发会根据auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
参数确定触发时机 auto-aof-rewrite-min-size
表示运行重写时,AOF
文件的最小体积,即小于该大小不会触发重写,默认为64M
auto-aof-rewrite-percentage
表示当前AOF
文件空间与上一次重写后AOF
文件空间的比值,当超过该比值才执行重写 所以自动触发重写的时机为:aof_current_size>auto-aof-rewrite-min- size&&(aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite- percentage
RDB 与 AOF 对比
RDB
保存着某个时间点的数据快照,因此RDB
文件非常适合备份。比如你可以每天备份一次数据库中的文件,并在需要的时候恢复某个时间点的数据RDB
数据恢复的时间要比AOF
快AOF
数据安全性更高,当服务器宕机时丢失的数据往往更少(取决于fsync策略
)AOF
是一个只追加的日志文件,且内容是可读的,适合紧急误删恢复
如何选取持久化方案
- 当
Redis
作为缓存使用时,一般不用开启持久化机制 - 如果将
Redis
作为持久化数据库使用,可以同时开启RDB
与AOF
持久化,定期执行bgsave
做数据快照备份,使用AOF
保证数据不丢失
参考
- Redis Persistence: redis.io/topics/pers…
- 《Redis 开发与运维》
喜欢我的文章可以搜索huangxy
关注我的公众号,也可以扫下放二维码关注