由于redis是基于内存的数据库,所以如果发生意外将会导致数据丢失,为尽量减少数据丢失,redis提供持久化功能。

Redis 支持以下两种持久化方式

1.快照形式RDB形式。(默认开启)

2.Aof形式。命令形式存储。(需要手动开启)

RDB 持久化方式

RDB文件是一个经过压缩的二进制文件。

以下为配置方式

redis关闭持久化配置 redis持久化设置_redis


save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“”的关系,“save 900 1”表示15分钟(900秒钟)内至少1个键被更改则进行快照,“save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照。“save 60 10000”,表示每一分钟(60秒钟)内至少有10000个键被更改则进行快照。

手动生成RDB快照,进入redis客户端执行save或bgsave可以生成dump.rdb文件,每次执行命令都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有的rdb快照文件。save是同步命令,bgsave是异步命令,bgsave会从redis主进程fork(fork是linux的一个函数)出一个子进程专门用来生成rdb快照文件。

AOF持久化方式

AOF持久化是通过保存redis服务器所执行的写命令来记录数据库状态,也就是当redis执行一个改变数据集的命令时,比如(set)这个命令就会被追加到AOF文件末尾。

以下为配置方式

redis关闭持久化配置 redis持久化设置_redis_02


开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。

AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof。

AOF持久化支持三种不同的刷新aof文件

appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
appendfsync everysec #先写到内存中然后每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。(默认方式)
appendfsync no #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。

AOF和RDB我们应选择哪种持久化方式

命令

RDB

AOF

启动优先级



体积



恢复速度



数据安全性

容易丢数据

根据策略决定

redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更完整一些。

因为无论是rdb还是aof持久化方式都有各自的优缺点,所以从Redis 4.0版本后支持混合持久化方式

重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志恢复,但是 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。通过如下配置可以开启混合持久化:

#aof-use-rdb-preamble yes

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再加载增量 AOF 日志就可以完全替代之前的AOF 全量文件,因此重启效率大幅得到提升。混合持久化AOF文件结构

redis关闭持久化配置 redis持久化设置_持久化_03


总结一句话就是,重写这一刻起,之前的内存生成RDB快照,之后的生成AOF文件格式的内容(命令行记录),将两类文件统一放到appendonly.aof文件中。

注意事项:

如果想把正在运行的redis数据库,从RDB切换到AOF,建议先使用动态切换方式,再修改配置文件,重启数据库。
(不能直接修改配置文件,重启数据库,否则数据库中数据就为空了。因为直接修改配置文件,重启之前数据存储在rdb文件中,当重启后是从aof文件中恢复数据,所以为空)

笔者实际开发遇到的情况:

条件:开启Aof持久化方式,并且执行flushall(清除所有的数据)。
出现情况:rdb文件大小被初始化了,但是aof文件却增加了。
原因:aof文件记录的是修改数据的操作,所以文件是追加形式的,flushall命令被追加到最后。
但是重启redis后,执行keys *里面没有记录,但是aof文件还是没有初始化。
解决方案:执行bgrewriteaof。让aof合并重写,因为aof文件的最后一条记录的flushall操作,前面的记录都无效了,合并所有操作之后就初始化了。