Redis的持久化操作配置和原理

RDB是redis将内存数据存储到磁盘文件的其中一种方式(另一种是AOF)。我们可以在redis.conf文件中,做一些针对RDB的设置。参考“redis 配置文件 snapshotting RDB数据库快照部分”,有中英文的对照翻译。

  1. ################################ 快照 #################################
  2. #
  3. # Save the DB on disk:保存数据库到磁盘
  4. #
  5. # save <秒> <更新>
  6. #
  7. # 如果指定的秒数和数据库写操作次数都满足了就将数据库保存。
  8. #
  9. # 下面是保存操作的实例:
  10. # 900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)
  11. # 300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)
  12. # 60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)
  13. #
  14. # 注释:注释掉“save”这一行配置项就可以让保存数据库功能失效。
  15. #
  16. # 你也可以通过增加一个只有一个空字符串的配置项(如下面的实例)来去掉前面的“save”配置。
  17. #
  18. # save ""
  19. save 900 1
  20. save 300 10
  21. save 60 10000
  22. #在默认情况下,如果RDB快照持久化操作被激活(至少一个条件被激活)并且持久化操作失败,Redis则会停止接受更新操作。
  23. #这样会让用户了解到数据没有被正确的存储到磁盘上。否则没人会注意到这个问题,可能会造成灾难。
  24. #
  25. #如果后台存储(持久化)操作进程再次工作,Redis会自动允许更新操作。
  26. #
  27. #然而,如果你已经恰当的配置了对Redis服务器的监视和备份,你也许想关掉这项功能。
  28. #如此一来即使后台保存操作出错,redis也仍然可以继续像平常一样工作。
  29. stop-writes- on-bgsave- error yes
  30. #是否在导出.rdb数据库文件的时候采用LZF压缩字符串和对象?
  31. #默认情况下总是设置成‘yes’, 他看起来是一把双刃剑。
  32. #如果你想在存储的子进程中节省一些CPU就设置成'no',
  33. #但是这样如果你的kye/value是可压缩的,你的到处数据接就会很大。
  34. rdbcompression yes
  35. #从版本RDB版本5开始,一个CRC64的校验就被放在了文件末尾。
  36. #这会让格式更加耐攻击,但是当存储或者加载rbd文件的时候会有一个10%左右的性能下降,
  37. #所以,为了达到性能的最大化,你可以关掉这个配置项。
  38. #
  39. #没有校验的RDB文件会有一个0校验位,来告诉加载代码跳过校验检查。
  40. rdbchecksum yes
  41. # 导出数据库的文件名称
  42. dbfilename dump.rdb
  43. # 工作目录
  44. #
  45. # 导出的数据库会被写入这个目录,文件名就是上面'dbfilename'配置项指定的文件名。
  46. #
  47. # 只增的文件也会在这个目录创建(这句话没看明白)
  48. #
  49. # 注意你一定要在这个配置一个工作目录,而不是文件名称。
  50. dir ./


上面的配置是很简单的,现在主要了解下RDB的工作机制和优缺点。当条件满足,redis需要执行RDB的时候,服务器会执行以下操作:

1. redis调用系统函数fork() ,创建一个子进程。

2.子进程将数据集写入到一个临时 RDB 文件中。

3.当子进程完成对临时RDB文件的写入时,redis 用新的临时RDB 文件替换原来的RDB 文件,并删除旧 RDB 文件。


在执行fork的时候操作系统(类Unix操作系统)会使用写时复制(copy-on-write)策略,即fork函数发生的一刻父子进程共享同一内存数据,当父进程要更改其中某片数据时(如执行一个写命令 ),操作系统会将该片数据复制一份以保证子进程的数据不受影响,所以新的RDB文件存储的是执行fork那一刻的内存数据

Redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候RDB文件都是完整的。这使得我们可以通过定时备份RDB文件来实 现Redis数据库备份。RDB文件是经过压缩(可以配置rdbcompression参数以禁用压缩节省CPU占用)的二进制格式,所以占用的空间会小于内存中的数据大小,更加利于传输。

除了自动快照,还可以手动发送SAVE或BGSAVE命令让Redis执行快照,两个命令的区别在于,前者是由主进程进行快照操作,会阻塞住其他请求,后者会通过fork子进程进行快照操作。 


Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将一个记录一千万个字符串类型键、大小为1GB的快照文件载入到内 存中需要花费20~30秒钟。 


通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。


RDB的优点是:

1.RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集。这种文件非常适合用于进行备份

和灾难恢复。

2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。

3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。


RDB缺点:

1.如果你需要尽量避免在服务器故障时丢失数据,那么RDB 不适合你。 虽然Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。

2.每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。,

猜你喜欢

转载自blog.csdn.net/chen213wb/article/details/80975138