Redis持久化机制详解
一、Redis为什么需要持久化机制
Redis一般用作缓存,其数据存储在内存中,当Redis宕机后,内存中的数据将会丢失。因此使用缓存的时候,我们经常需要对内存中的数据进行持久化也就是将内存中的数据写入到硬盘中
Redis 不同于 Memcached 的很重要一点就是,Redis 支持持久化,而且支持 3 种持久化方式::
- 快照(RDB)
- 只追加文件(AOF)
- RDB 和 AOF的混合持久化(Redis4.0新增)
二、RDB持久化
(一)什么是RDB持久化
1、快照持久化:在指定的时间间隔内将内存中的数据以快照的形式写入磁盘(内存中的数据以二进制序列化的形式写入磁盘)
2、在满足默认配置的RDB生成时,Redis会fork出子进程来进行持久化,不阻塞主进程的执行。子进程将数据写入临时文件,然后替换旧的RDB文件进而完成磁盘的写入,主进程可以处理读写请求。
RDB快照持久化是Redis默认采用的持久化方式,RDB默认配置的生成策略如下:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。
(二)RDB持久化的优、缺点
优点:
- 1、直接存储内存数据的二进制序列化形式,占用磁盘更小
- 2、宕机后重启恢复的速度比AOF快
缺点:
- 数据的实时性及安全性要差一些
- RDB持久化是需要Redis fork出子进程来执行持久化,频繁的执行成本较高
三、AOF持久化
(一)什么是AOF持久化
AOF(append only file)只追加文件:与快照持久化(RDB)相比,AOF持久化的实时性更好。AOF持久化默认是不开启的(Redis6.0 版本之后默认是开启的)
开启AOF持久化后每执行一条能改变Redis中数据的命令,1、Redis服务器就会将该指令追加到AOF缓冲区 2、然后调用write函数将数据将数据写到系统内核缓冲区(注意!!此时并没有同步到磁盘) 3、最后根据持久化方式(fsync策略)将缓存区的数据同步到磁盘中。
根据如上所述我们可以概述出,AOF工作基本流程。
(二)AOF持久化的基本流程
AOF持久化功能的实现可以简单分为5步:
- 1、命令追加(append):Redis所执行的所有的写命令会追加到AOF缓冲区。
- 2、文件写入(write):这一步需要调用write函数(系统调用)将数据写入到系统缓冲区,注意!!! 此时并没有写到磁盘
- 3、文件同步(fsync):根据对应的持久化方式(fsync策略),调用fsync函数,进行磁盘的同步操作
- 4、文件重写(rewrite):随着AOF文件越来越大,需要定期进行AOF的重写,来达到压缩的目的(注意:AOF重写并非是对旧的AOF文件进行重写来达到压缩的目的,而是通过重新去获取最新执行的Redis指令并生成一个新的AOF文件进而替换旧的AOF文件来完成重写:fork + 双写)
- 5、重启加载(load):当Redis重启时,可以加载AOF文件进行数据恢复
(三)AOF持久化的三种回写策略(fsync策略)
Redis提供了三种不同的AOF持久化方式(fsync回写策略),分别是:Always、Everysec、No三种回写策略。
- 1、Always:主线程调用write将数据写入到系统缓冲区后,立即调用fsync函数将数据同步到AOF文件,完成后线程返回。这样严重降低Redis的性能(write + fsync)
- 2、Everysec:主线程调用write将数据写入系统缓冲区后立即返回,由后台线程每隔1s调用fsync函数将数据同步到AOF文件(write + fsync ,fsync时间间隔为1s)
- 3、No:主线程调用write将数据写入系统缓冲区后立即返回,由操作系统决定何时进行同步。Linux下一般为30S一次(write 但不fsync,fsync的时机由操作系统决定)
(四)AOF重写
随着AOF文件变得越来越大,系统的性能将会受到影响,所以我们需要进行AOF的重写来达到压缩的目的。
我们这里需要注意AOF重写并非是对旧的AOF文件进行重写,而是根据缓存中最新的Redis指令生成一个新的AOF文件进而替换旧的AOF文件来完成重写。重写期间Redis还会维护一个AOF重写缓冲区
AOF重写逻辑主要分为两步:fork + 双写
- 1、主线程先fork出子进程,子进程复制父进程的虚拟页表(此处为什么不是直接拷贝数据而是复制虚拟机页表呢,是为了防止一次性拷贝大量数据导致主线程阻塞过长和内存浪费的问题)
- 2、子进程读取内存中的数据并写到AOF重写缓冲区进而同步到新的AOF文件中
- 3、重写期间,主进程还是会正常接收写命令,新的命令不仅会写入AOF旧的文件,还会写入AOF新的文件,保证重写的过程中发生宕机旧的AOF文件还是全的
- 4、重写完成后将新的AOF文件替换旧的AOF文件。
三、混合持久化
(一)AOF持久化
优点:
AOF持久化实时性更强,数据安全性更高
缺点:
AOF文件需要定期进行瘦身,宕机后恢复速度相比与RDB持久化要慢
(二)RDB持久化
优点:
DRB持久化存储的是二进制序列化的数据,宕机后恢复速度要比AOF持久化要快
缺点:
数据的实时性及安全性要差一些。
Redis4.0 提出了混合使用AOF和RDB的方式。
RDB快照按照一定的频率生成,两次快照间增量命令记录到AOF文件中。这种混合持久化即具备RDB的快速恢复能力,同时也具备跟高的数据安全性。