redis是内存数据库,即数据库状态都是存储于内存中,因此,当服务器重启或者断开后,数据便会丢失;为了解决数据丢失问题,便需要将数据从内存保持到磁盘中,这就是redis的数据持久化

目前,redis实现了两种数据库持久化方案,一种是RDB,另一种是AOF,让我们来聊聊这两种方案


RDB

redis database,即将数据库的内容(key-value)保存为压缩的二进制文件

即便redis服务进程退出,但是RDB文件仍然存在,这样当redis启动时便会自动载入RDB文件以此保证数据不丢失,其流程如下 rdb流程

1.手动生成RDB文件

redis有两个命令用于生成RDB文件,即SAVEBGSAVE,这两个指令的用途都是一样的,唯一的区别在于

  1. SAVE会直接堵塞服务器进程,知道RDB文件创建完毕为止,这会导致在此期间服务器不能处理任何命令请求
  2. BGSAVE不会堵塞服务器进程,而是会fork派生出一个子进程用于执行RDB创建,在此期间服务器主进程(父进程)仍可以继续处理命令请求

其实现源码位于rdb.c中的rdbSave()rdbSaveBackground()函数,有兴趣的小伙伴可以去看看

从区别来看,很明显,在执行RDB文件的创建首选指令BGSAVE

2.自动生成RDB文件

一般来说RDB文件的生成并不需要用户去手动执行,redis提供了save指令允许用户设置执行条件:在多少时间内服务器进行多少次修改;例如指令save 500 1即表示服务器如果满足在500秒之内对数据库执行了至少1次修改,那么就会执行RDB文件的生成

在redis的serverCron()时间事件中会去判断是否满足条件并执行RDB文件生成

3.自动加载RDB

RDB文件的生成可以手动执行,但是redis目前并没有提供手动加载RDB文件的操作指令,即RDB文件的载入工作是在服务器启动的时候自动执行的,并且在服务器载入RDB文件期间会一直处于堵塞状态


AOF

Append Only File,通过将redis服务器所执行的写指令保存为AOF文件来记录数据库状态

1.何时写入

当用户执行redis写操作时,便会将指令保存到AOF文件中,其流程如下 aof流程图

2.关于AOF重写

问题:随着数据库服务器运行,AOF文件中的内容会越来越多,因为每一条写指令都需要记录,也因此执行AOF文件来进行数据还原的时间也就越久

解决方案:为了解决这个问题,redis提供了AOF重写BGREWRITEAOF指令;原理即从数据库中读取键现在的值,然后用一条指令去记录键值对,代替之前的多余命令,并重新生成一套写指令存储为新的AOF文件,并替换掉旧的AOF文件,这样新AOF文件就不会存在过多的冗余指令,体积包括执行时间也会小很多

3.何时加载AOF

当服务器重启动时会先检测是否有AOF文件,如果有就会载入AOF文件来实现数据一致,如果没有AOF则会检测是否执行RDB载入流程


加载

当服务器启动时会先检测是否有AOF文件,如果有则加载AOF文件,如果没有则会判断是否有RDB文件存在,如果有RDB文件,则加载RDB文件

数据持久化加载流程

相关文档:

redis设计与实现

redis进阶: 过期删除策略

redis进阶: redisObject对象详解

原文地址:

redis进阶: 数据持久化

Happy coding!