redis的持久化即redis提供的RDB持久化和AOF持久化。
RDB
RDB即redis database。redis会在从配置文件中(redis.conf)读取数据,然后按照配置文件中指定的时间间隔,指定的触发条件,然后将内存中的数据集快照写入磁盘,即为snapshot快照。恢复时将快照文件直接读取到内存中。
运行流程:
- Redis会单独创建(fork)一个子进程来进行持久化,会先将内存中的所有数据写入到 一个临时文件中。
- 整个过程中,主进程是不进行任何IO操作的,继续处理client请求。
- 待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。
所以!!RDB持久化机制每次快照持久化都是将内存数据完整写入到磁盘一次,并不 是增量的只同步脏数据!!大量的写操作可能影响性能
什么是Fork?
Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
所以!!RDB持久化机制有子进程和父进程
RDB的相关知识:
redis会从配置文件中的SNAPSHOTTING模块读取对于RDB持久化机制的相关配置。
RDB默认保存的数据文件是dump.rdb,默认当前路径下
RDB的默认触发条件是:
1). save 900 1 即900秒内,如果有1个key被修改,即进行快照操作
2). save 300 10 即300秒内,如果有10个key被修改,即进行快照操作
3). save 60 10000 即60秒内,如果有10000个key被修改,即进行快照操作用户可以通过save命令和bgsave命令进行提前触发RDB机制
1). save命令是在主线程上保存快照的。redis的主线程是用来干嘛的?用来处理redis client请求的。save保存到只管保存,其他不管,这样必将会堵塞其他所有client请求
2). bgsave命令:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间执行flushall命令后,也会触发RDB机制,会产生dump.rdb文件覆盖掉原本的持久化文件,但是这个持久化文件是空的,没有任何数据!
RDB持久化文件如何恢复?
当client到来,redis会根据配置文件中配置的地址和文件名找到rdb持久化文件,自动将其扫描进内存,所以只需要把rdb持久化文件放置到配置文件中指定的位置,命名为指定的文件名即可进行恢复。
默认:redis安装目录当前位置下的dump.rdb文件。为了防止产生意外,备份了一份rdb文件。在恢复的时候只需要放置在这个位置即可
RDB优势和劣势?
优势
- 方便备份,RDB的运行原理意味着会产生一份数据RDB文件,可以很简单容易的归档,整理,或者移动位置。
- 适合大规模的数据恢复,因为是直接读取到内存中的,相比AOF机制要快
- 最大化redis的性能;有父子进程,各自负责不同的方面
- 对数据完整性和一致性要求不高
劣势
- RDB的持久化机制是一段时间做一次备份(保存点),如果在最后一次还没备份的话,redis产生意外,那么会丢失最后一次快照的所有修改操作
- RDB是有父进程和子进程的。子进程的所有东西都和父进程一模一样,那就意味着在内存中的数据会被克隆一份。同样的数据会有两份,两倍的膨胀量。
AOF
aof即Append Only File。相关配置在redis的Append Only File模块中有。AOF持久化机制是以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件!!
注意,是追加操作,与RDB全部数据重新覆盖不同
运行流程:
redis启动之初会读取日志文件中的写命令在内存中重新构造数据。换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。所以这也是AOF在数据恢复上不如RDB快的原因
AOF的相关知识:
AOF默认保存的日志文件是appendonly.aof,默认当前路径下
AOF触发同步写入日志文件的条件:AOF有三种触发策略,根据你在配置文件配置项的不同,会刷新日志文件,追加更改数据的命令
1).appendfsync always 每修改同步,同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
2).appendfsync everysec 每秒同步,异步持久化 如果一秒内宕机,有数据丢失
3).appendfsync no 从不同步redis的AOF持久化机制默认是关闭的,需要在配置文件中将appendonly属性设为yes将AOF机制启动
- AOF的恢复默认只需要在当前路径下存在一个appendonly.aof这个文件,即可。redis会根据日志文件中的修改命令重构整个数据机构。
- 如果AOF文件或者RDB文件遭受损坏,或者在文件中语句有错,无法排查。可以使用命令进行异常修复。同理RDB也有一条命令可以进行异常修复
redis-check-aof --flx AOF文件名
redis-check-dump --flx dump文件名
这两个命令实际是调用两个文件,这两个文件在你当前目录存在,与AOF文件和ROB文件同个目录下
AOF的rewrite(重写)机制
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制.
当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof提前触发
重写原理:
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),
遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似
触发机制
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
AOF优势和劣势?
优势
- 相较RDB,AOF对数据的一致性和完整性的支持更高,但仍然可能丢失最后一秒的数据
劣势
- 相同的数据集,AOF文件大小要大于RDB文件,恢复速度也要慢于ROB
- AOF的每修改同步策略运行效率低于RDB,因为RDB是父子进程,异步。但每秒同步策略效率较高,不同步策略与RDB相同
持久化篇总结
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
- 支持同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
- DB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?建议不要,因为RDB更适合用于备份数据库