Redis是内存数据库,如果不将内存中数据库状态保存到磁盘,那么一旦服务进程退出,服务器中数据库状态也会消失,所以Redis提供了持久化功能
RDB(Redis DataBase)
什么是RDB
在指定时间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,他恢复时是将快照文件直接读到内存中。
Redis会单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要大规模数据恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF更加高效,RDB的缺点是最后一次持久化后的数据可能丢失。
在生产环境,会对rdb文件进行备份。
总结下RDB的流程:
(1)redis根据配置自己尝试去生成rdb快照文件
(2)fork一个子进程出来
(3)子进程尝试将数据dump到临时的rdb快照文件中
(4)完成rdb快照文件的生成之后,就替换之前的旧的快照文件
dump.rdb,每次生成一个新的快照,都会覆盖之前的老快照
rdb保存的文件名是dump.rdb 都是在我们的配置文件快照中进行配置
触发机制
1、save规则满足的情况下,会自动触发rdb规则。
2、执行flushall命令,也会触发rdb规则。
3、退出redis,也会触发rdb规则
如何恢复rdb文件!
redis在启动时会自动检查配置文件中配置的rdb目录下的dump.rdb文件。
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis" #如果这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据
优点:
1、适合大规模的数据恢复!
2、对数据完整要求不高!
缺点:
1、需要一定时间间隔进行操作!如果redis意外宕机了,最后一次修改的数据就没有了!
2、fork进程的时候,会占用一定的空间!
AOF appendonly
以日志的形式来记录每个写操作,将Redis所有执行过的指令记录下来(读操作不记录),只许追加文件不许修改文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就会根据日志文件的内容将写指令从前到后执行一遍以完成数据恢复工作。
aof保存的文件是appendonly.aof
默认是不开启的,我们需要手动配置,只要将appendonly设置为yes即可开启aof,重启redis即可生效
如果这个aof文件有错误,这个时候redis是启动不起来的,我们需要修复这个aof文件
redis给我们提供了一个工具,redis-check-aof --fix
(他会删除文件中错误的那一项操作)
AOF的流程如下:
(1)redis fork一个子进程
(2)子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志
(3)redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件
(4)子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
(5)用新的日志文件替换掉旧的日志文件
AOF的原理是直接把用户插入到服务器的命令追加到结尾,那么文件会原来越大,一些重复的写命令也会越来越多,这时,我们可以利用BGREWRITEAOF 命令来重写AOF,重写的配置如下:
auto-aof-rewrite-percentage 100 #aof文件大小超过上次重写时文件大小的百分之几开始重写,如果之前没有写过,则根据启动时文件大小。
auto-aof-rewrite-min-size 64mb #限制允许重写时的最小文件大小。
优点:
1、每一次修改都同步,文件的完整性会更好
2、每秒同步一次,可能会丢失一秒的数据
3、从不同步,效率是最高的
缺点
1、相对于数据文件来说,aof远大于rdb,修复速度也比rdb慢。
2、aof运行效率也要比rdb慢
AOF和RDB同时工作:
(1)如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting
(2)如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite
(3)同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整