介绍
Redis是运行在内存中的数据库,当我们关闭了Redis服务器后,内存中的数据会丢失吗?
答案是不会的,因为Redis有持久化功能,能够将内存中的数据保存到磁盘中的文件,以此来实现数据的永久保存。
在Redis中,有两种持久化功能:
- RDB持久化功能,简称RDB快照
- AOF持久化功能,简称AOF日志
关于RDB快照,建议先去看看我的这篇文章Redis持久化——RDB快照_秋天code的博客-CSDN博客
AOF日志
AOF的全称是,Append Only File,日志文件追加写。
AOF日志记录的是每次对数据进行修改的命令,通过这些命令就可以恢复数据库状态
注意:读命令是不会被记录到AOF日志中的,因为不涉及数据的变化。
Redis每执行一条写命令,就会把该命令以追加的方式写入到AOF日志文件中,然后在Redis服务器启动时,就会通过此日志文件中的命令,来恢复数据库状态,大致的工作流程:
在Redis中,默认开启的是RDB持久化功能,并没有开启AOF持久化功能,因此我们修改配置项来开启AOF持久化功能:
appendonly yes // 表示开启AOF持久化(no关闭)
appendfilename "appendonly.aof" // AOF日志文件的名称
AOF日志写回时机
对AOF日志文件追加写的操作是IO操作,肯定是比内存操作要慢的,又因为Redis是单线程的,所以IO操作会阻塞后面的请求,因此为了提高Redis的性能,会在内存中有一块缓冲区,专门用来存放每次写命令产生的AOF日志,将缓冲区中的命令批量写回到AOF文件中。
先来看AOF日志写入的详细流程图:
Redis中提供了3种写回策略,控制以上的第三步,即调用操作系统的IO操作的时机。
在Redis的配置文件中,appendsync
配置项就是用来配置AOF的回写策略,有三个值Always
、Everysec
、No
Always
,每次执行写操作命令完成后,同步将AOF日志写回磁盘Everysec
,每秒,每次执行写操作命令,会先记录此命令到内存中的AOF缓冲区,隔1秒后,将缓冲区中的AOF日志写回到AOF文件中。No
,不由Redis控制写回硬盘的时机,转交给操作系统控制。也就是说,每次写操作命令执行完后,先将命令写入到内存中的AOF缓冲区,再由操作系统来决定何时将此缓冲区中的内存写回到磁盘文件中。
总结这三种策略:
AOF重写机制
AOF日志文件,随着执行写操作的命令次数越来越多,文件的大小会越来越大。
当一个AOF日志文件过大时,就会严重影响性能:当Redis服务器启动时,需要从AOF日志文件中恢复数据,Redis是单线程的,会逐条执行其中的命令,当AOF文件过大时,命令也会很多,整个数据恢复过程就会很慢。
Redis为了避免AOF日志文件过大的问题,提供了AOF重写机制,当AOF文件的大小超过设定的阈值时,Redis就会启动AOF重写机制,来压缩AOF文件
具体的原理是:
AOF重写机制是在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到新的AOF文件中,等到全部记录完成后,就会将新的AOF文件替换掉旧的AOF文件,AOF文件的体积会大大缩小。(因为一条记录、键值对,可能会对应多次写操作,我们只需要记录最终此键值对的状态即可,因此就会把原来旧的AOF文件中的对同一键值对写的命令,最终替换成一条写命令,所以AOF文件体积会缩小)
AOF和RDB对比
- AOF日志文件是文本文件,记录的是所有的写命令;而RDB文件是二进制文件,记录的就是数据本身。
- AOF日志恢复数据的速度较慢,即在服务器启动时占用的时间较长。RDB文件的载入会较快。(因为AOF持久化功能会把AOF日志中的每条命令再执行一遍,当AOF日志非常大时,需要执行的命令就非常多,而且Redis是单线程的,需要一条一条的执行,所以恢复数据的效率较低)
参考文章
- 《Redis设计与实现》
- AOF 持久化是怎么实现的? | 小林coding