Redis的持久化策略

Posted 木易yang~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis的持久化策略相关的知识,希望对你有一定的参考价值。

Redis的持久化策略:

  我们都知道,Redis是一个键值对的数据库服务器,服务器中包含着若干个非空的数据库,每个非空的数据库中包含任意个键值对,它将自己的数据都存储在内存中,如果我们不采取措施将在内存中的数据保存到磁盘中的话,如果一旦出现服务器宕机的情况下,服务器中的数据库数据也会随之而消失。这时候,Redis就提供了两种Redis的持久化功能:RDB持久化和AOF持久化。

一、RDB持久化功能

  RDB通过保存数据库中的键值对来记录数据库状态的不同。

  RDB既可以手动置顶,也可以配置服务器选项进行定期执行,实现是将某个时间点上的Redis数据库中的数据保存到一个RDB文件中,RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成时的Redis数据库数据。

  • 创建文件

  一般的话,是有两个Redis的命令可以用于生成RDB文件,一个是SAVE,一个是BGSAVE。其中SAVE命令在执行是,会阻塞服务器进程,直到RDB文件创建成,在进程阻塞期间,服务器不能进行任何请求操作。另一个BGSAVE命令的方式则是派生一个子进程,由子进程负责创建RDB文件,服务器进程继续处理请求。创建RDB文件的实际工作由rdb.c/rdbSave函数来执行,两种命令分别以不同的方式来调用函数执行。

  • 读取文件

  读取RDB文件是在服务器启动的时候自动完成的,只要再Redis服务器启动的时候有检测到RDB文件的存在,就会自耦东读取RDB文件。

  • 计数器(dirty)与最后一次修改(lastsave)属性

  Redis服务器中维持着一个dirty技术区和一个lastsave属性,用来判断是否执行保存命令

    • dirty记录着距离上一次执行SAVE或者BGSAVE命令之后服务器对数据库进行的操作次数
    • lastsave属性时一个时间戳,记录着服务器上一次执行SAVE和BGSAVE命令的时间
  • 保存时间间隔

  BGSAVE可以在不阻塞服务器进程的情况下执行,所以我们可以配置服务器的save选项,让服务器每间隔一段时间自动执行一次BGSAVE命令。服务器默认设置save选项如下:

1 save     900     1
2 save     300     10
3 save     60      10000

  对应的意思是:

    • 服务器在900秒之内,对数据库进行了超过一次修改,就会执行BGSAVE命令
    • 服务器在300秒之内,对数据库进行了超过10次修改,就会执行BGSAVE命令
    • 服务器在60秒之内,对数据库进行了超过10000次修改,就会执行BGSAVE命令

  我们可以通过制定配置文件或者传入启动参数的方式来设置save选项

  • serverCron函数

  一个默认没间隔100毫秒就会执行一次的函数,它的任务之一就是检查save选项所设置的保存条件是否满足,满足的情况下,就执行BGSAVE命令。

二、AOF持久化功能

  AOF持久化是通过保存Redis服务器所执行的命令来记录数据库状态的,被写入AOF的所有命令都是以Redis的请求协议格式来进行保存的。它的整个执行流程大致分为三步:

    • 命令追加(append):当AOF持久化功能开启的状态下,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令
    • 文件写入:当服务器接收到命令时,会调用一个flushAppendOnlyFile函数,考虑是否将aof_buf缓冲区中的内容写入和保存到AOF文件中。函数的持久化行为由服务器配置的一个appendfsync选项的值来决定,下面是对应关系:
      • always:将aof_buf缓冲区的所有内容写入并同步到AOF文件中
      • everysec:将aof_buf缓冲区的所有内容写入AOF文件中,同时,如果距离上次同步行为间隔一秒钟,name将再次对AOF文件进行同步,服务器分配一个单独的线程来执行这个操作,everysec是默认值
      • no:将aof_buf缓冲区的所有内容写入AOF文件中,但不对AOF文件进行同步,具体的同步时间由系统来决定
    • 文件同步:上面的文件写入只是文件被暂时的存储在一个内存缓冲区中,等到缓冲区的空间被填满,或者超过了一定的时间限制的时候,才会将缓冲区的数据写入到磁盘中,我们将这个过程成为文件的同步
  • 读取文件

  读取文件的执行点同时是在服务器启动的时候。因为AOF文件中包含了重建数据库的所有命令,所以服务器只要重新执行一遍AOF文件中保存的命令,就可以还原数据库保存之前的数据。Redis通过创建一个没有网络连接的伪客户端来执行AOF中保存的写命令。步骤为:

    • 从AOF文件中分析并读取一条写命令
    • 使用为客户端执行被当初的命令
    • 重复执行前面两个步骤,直到文件中所有的内容都被读取完毕
  •  AOF文件重写

  我们知道AOF文件中保存的是每一次执行的命令,随着时间的进行,AOF文件的中的内容会越来越多,但是当Redis客户端即执行了添加,也执行了删除的语句之后,我们可以简单的使用一个新的命令也能够达到数据库中数据一致的状态,这时候就讲到了Redis的文件重写功能。

  服务器通过创建一个新的AOF文件来替代原有的AOF文件,新旧两个文件保存相同的数据库状态,但是新的文件不会包含任何冗余的命令,大大减小了AOF文件的体积。

  AOF文件的重写功能是通过读取当前的数据库状态来执行的。并不会对原有的AOF文件进行任何的操作。具体的执行是通过调用aof_rewrite函数来执行的,而为了避免影响服务器的性能,这个也是单独开辟线程来执行的,为了避免在执行重写过程中的数据不一致问题,Redis服务器还设置了一个重写缓冲区来执行在重写过程中追加的命令

三、补充

  AOF文件的更新频率高于RDB文件

  • 只要服务器开启了AOF持久化功能,服务器会有限使用AOF文件来还原数据库状态
  • 只有在AOF持久化功能处于关闭的情况下,服务器才会使用RDB文件来还原数据库状态

 

以上是关于Redis的持久化策略的主要内容,如果未能解决你的问题,请参考以下文章

Redis持久化策略

Redis的持久化策略

Redis持久化策略(看这篇,你肯定会有所获)

Redis篇:持久化淘汰策略,缓存失效策略

Redis篇:持久化淘汰策略,缓存失效策略

关于redis的持久化策略