Redis的持久化机制
持久化机制
进行持久化的方式:
- AOF日志:每执行一条写操作的命令,就把该命令以追加的方式写入到一个文件里。
- RDB快照:将某一时刻的内存数据以二进制的方式写入磁盘
- 混合持久化方式:集成了AOF和RDB的优点
AOF日志

先执行命令再写日志的优缺点
优点:
- 避免了额外的检查开销:因为是在执行成功后才写日志,所以能写日志则说明可以通过语法检查,避免了再单独检查。
- 不会阻塞当前写操作命令的执行:因为当写操作命令执行成功后才会将命令记录到AOF日志中
缺点:
- 数据可能会丢失:因为写操作命令和记录日志是两个过程,可能会出现写完操作命令还没来得及日志写磁盘宕机丢失。
- 可能会阻塞其他操作:虽然是在写完命令操作后再写日志,不会阻塞写操作命令,但是由于也是在主线程中执行,可能会阻塞后续的操作。
AOF日志执行过程

- redis执行完写命令操作后,会将命令追加到server.aof_buf缓冲区
- 调用write将aof_buf缓冲区的数据写入到AOF文件,此时处于page cache,等待内核将数据写入硬盘
- 具体内核缓冲区写入硬盘的时机由内核决定。
写回策略:
- Always:每次写操作命令执行完后都同步将AOF日志写回硬盘
- Everysec:每次写操作命令执行完后先将命令写入到AOF文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘
- No:每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。
重写机制:
为了避免AOF日志越写越大,Redis提供了重写机制,当AOF大小超过了阈值就会重写。
在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到新AOF文件中,全部记录完后替换掉旧文件。
由后台子进程 bgrewriteaof完成
- 子进程在进行AOF重写时,主进程仍然可以继续处理命令请求,不会被阻塞。
- 用子进程避免了用线程时需要加锁的情况,不会降低性能。使用子进程可以共享物理内存,但是是只读的。不需要进行加锁
重写过程中,主进程仍然处理命令操作,此时主进程若修改已经存在的KV数据则会发生写时复制,为了解决这个问题redis设置了AOF写缓冲区,重写AOF期间Redis每写完一个命令后会同时将这个写命令写入到AOF缓冲区和AOF重写缓冲区中。当子进程完成重写后会给主进程发一条信号,主进程收到信号后会调用一个信号处理函数:
- 将AOF重写缓冲区的内存追加到新AOF文件
- 将新的AOF文件改名并覆盖现有的AOF文件
RDB快照
记录了某一瞬间的内存数据,是全量快照,把内存中的所有数据都记录到磁盘中。redis恢复数据时用RDB恢复效率更高。不需要执行AOF里的命令。
生成RDB快照
提供了两个命令来生成RDB文件
- save:在主线程中生成RDB文件,如果写入RDB文件时间太长会阻塞主线程
- bgsave:创建一个子进程来生成RDB文件,避免阻塞主线程
redis还可以通过配置文件的选项实现每隔一段时间自动执行一次bgsave

- 900秒内对数据库进行了至少1次修改
- 300秒内对数据库进行了至少10次修改
- 60秒内对数据库进行了至少10000次修改
执行快照时修改数据
在执行bgsave时仍然可以继续处理操作命令,关键在于写时复制。
在执行bgsave命令时会创建子进程,与父进程共享同一片内存数据,因为创建子进程时会复制父进程的页表,但页表指向的物理内存还是一个,若主线程执行写操作,则被修改的数据会复制一份副本然后bgsave子进程会把该副本写入RDB文件,过程中主进程仍然可以直接修改原来的数据。
混合持久化
使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。
优点:
- 结合了RDB和AOF的优点,开头为RDB格式,使得Redis可以更快的启动,同时结合了AOF的优点,降低了大量数据丢失的风险
缺点:
- AOF文件中添加了RDB格式,文件可读性变差。
- 兼容性差,不能用在Redis4.0之前版本。

浙公网安备 33010602011771号