RDB

在运行情况下, Redis 以数据结构的形式将数据维持在内存中, 为了让这些数据在 Redis 重启之后仍然可用, Redis 分别提供了 RDB 和 AOF 两种持久化模式。

在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中, 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态。

RDB 功能最核心的是 rdbSaverdbLoad 两个函数, 前者用于生成 RDB 文件到磁盘, 而后者则用于将 RDB 文件中的数据重新载入到内存中:

    如图

            

先介绍SAVEBGSAVE 命令的实现, 以及 rdbSaverdbLoad 两个函数的运行机制, 然后以图表的方式, 分部分来介绍 RDB 文件的组织形式。

    保存

  rdbSave 函数负责将内存中的数据库数据以 RDB 格式保存到磁盘中, 如果 RDB 文件已存在, 那么新的 RDB 文件将替换已有的 RDB 文件。

   在保存 RDB 文件期间, 主进程会被阻塞, 直到保存完成为止。
   SAVEBGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:

    1、SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。

    2、BGSAVEfork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为 rdbSave 在子进程被调用,所以 Redis 服务器在 BGSAVE 执行期间仍然可以继续处理客户端的请求。

  通过伪代码来描述这两个命令,可以很容易地看出它们之间的区别:

  def SAVE():

     rdbSave()

  def BGSAVE():

    pid = fork()

      if pid == 0: # 子进程保存

      RDB rdbSave()

    elif pid > 0: # 父进程继续处理请求,并等待子进程的完成信号

    handle_request()

    else:

     # pid == -1

    # 处理 fork 错误

    handle_fork_error()

    SAVE 、 BGSAVE 、 AOF 写入和 BGREWRITEAOF

    除了了解 RDB 文件的保存方式之外, 我们可能还想知道, 两个 RDB 保存命令能否同时使用? 它们和 AOF 保存工作是否冲突?

    SAVE

      前面提到过, 当 SAVE 执行时, Redis 服务器是阻塞的, 所以当 SAVE 正在执行时, 新的 SAVEBGSAVEBGREWRITEAOF 调用都不会产生任何作用。

      只有在上一个 SAVE 执行完毕、 Redis 重新开始接受请求之后, 新的 SAVEBGSAVEBGREWRITEAOF 命令才会被处理。

      另外, 因为 AOF 写入由后台线程完成, 而 BGREWRITEAOF 则由子进程完成, 所以在 SAVE 执行的过程中, AOF 写入和 BGREWRITEAOF 可以同时进行。

    BGSAVE

      在执行 SAVE 命令之前, 服务器会检查 BGSAVE 是否正在执行当中, 如果是的话, 服务器就不调用 rdbSave , 而是向客户端返回一个出错信息, 告知在BGSAVE 执行期间, 不能执行 SAVE

      这样做可以避免 SAVEBGSAVE 调用的两个 rdbSave 交叉执行, 造成竞争条件。

      另一方面, 当 BGSAVE 正在执行时, 调用新 BGSAVE 命令的客户端会收到一个出错信息, 告知 BGSAVE 已经在执行当中。

      BGREWRITEAOFBGSAVE 不能同时执行:

        1、如果 BGSAVE 正在执行,那么 BGREWRITEAOF 的重写请求会被延迟到 BGSAVE 执行完毕之后进行,执行 BGREWRITEAOF 命令的客户端会收到请求被延迟的回复。

        2、如果 BGREWRITEAOF 正在执行,那么调用 BGSAVE 的客户端将收到出错信息,表示这两个命令不能同时执行。

      BGREWRITEAOFBGSAVE 两个命令在操作方面并没有什么冲突的地方, 不能同时执行它们只是一个性能方面的考虑: 并发出两个子进程, 并且两个子进程都同时进行大量的磁盘写入操作, 这怎么想都不会是一个好主意。

    载入

     当 Redis 服务器启动时, rdbLoad 函数就会被执行, 它读取 RDB 文件, 并将文件中的数据库数据载入到内存中。

      在载入期间, 服务器每载入 1000 个键就处理一次所有已到达的请求,不过只有 PUBLISHSUBSCRIBEPSUBSCRIBEUNSUBSCRIBEPUNSUBSCRIBE 五个命令的请求会被正确地处理, 其他命令一律返回错误。等到载入完成之后,服务器才会开始正常处理所有命令。

      另外, 因为 AOF 文件的保存频率通常要高于 RDB 文件保存的频率, 所以一般来说, AOF 文件中的数据会比 RDB 文件中的数据要新。

      因此, 如果服务器在启动时, 打开了 AOF 功能, 那么程序优先使用 AOF 文件来还原数据。 只有在 AOF 功能未打开的情况下, Redis 才会使用 RDB文件来还原数据。

时间: 2024-10-15 17:06:58

RDB的相关文章

Redis两种持久化方式(RDB&AOF)

爬虫和转载请注明原文地址;博客园蜗牛:http://www.cnblogs.com/tdws/p/5754706.html Redis所需内存 超过可用内存怎么办 Redis修改数据多线程并发—Redis并发锁 windows下redis基础操作与主从复制 从而 数据备份和读写分离 Redis两种持久化方式(RDB&AOF) Redis的持久化过程中并不需要我们开发人员过多的参与,我们要做的是什么呢?除了深入了解RDB和AOF的作用原理,剩下的就是根据实际情况来制定合适的策略了,再复杂一点,也就

rdb map出错rbd sysfs write failed

创建了一个rbd镜像 $ rbd create --size 4096 docker_test 然后,在Ceph client端将该rbd镜像映射为本地设备时出错. $ rbd map docker_test --name client.admin rbd: sysfs write failed RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature

redis持久化之RDB

rdb和aof两种持久化机制 RDB:snapshot --> 存储的格式为二进制格式,是默认的持久化方式:按事先定制的策略,周期性地将数据从内存中读取保存到磁盘:数据文件默认为dump.rdb 所以rdb保存机制有两种: a.客户端也可以显式使用save或bgsave命令启动快照保存机制 b.在配置文件中使用保存策略进行保存 save:同步保存的:在主线程中保存快照,此时会阻塞所有客户端请求(如果内存中有大量数据,将会阻断客户请求的时间比较久) bgsave:异步保存的:主进程不会被阻塞,不影

第一章: 在RDB中的树结构数据

第一章: 在RDB中的树结构数据 在本章中,我将写一个基本的知识来理解这个问题 一  模型的作用 RBD处理树模型的作用总结为两点: 1  在RDB表中保存树的数据 2  效率的查询节点的相关节点 1  在RDB表中保存树的数据 我们可以定义的标准,该模型是否具有存储层次数据的功能 可以由保存的所有节点再现原有的层次结构 如果不能通过保存的数据再现原有的树结构,就不能说这个模型实现了树. 2  效率的查询节点的相关节点 通常,我们将数据保存到数据库中进行搜索,数据中保存了分层数据,可能会查询任何

(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about t

运行redis过程中,突然报错如下: (error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error. 解决方案(百度到的答案,不过确实有用):

Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk"问题的解决

异常详细信息 Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please chec

rdb文件解析及恢复

参见:rdb_parse rdb文件解析及恢复,布布扣,bubuko.com

Redis rdb文件CRC64校验算法 Java实现

查看RDB文件结构,发现最后的8字节是CRC64校验算得,从文件头开始直到8字节校验码前的FF结束码(含),经过CRC64校验计算发现,貌似最后的8字节是小端模式实现的. 参考redis的crc64实现的代码,点击查看 Java代码如下: 1 package com.jadic.utils; 2 3 /** 4 * @author Jadic 5 * @created 2014-5-15 6 */ 7 public class CRC64 { 8 private static final lon

RDB持久化

redis是一个内存数据库,所有我们需要将他定时存在磁盘上,如果没有开启AOF,那么会生成RDB文件进行存储,其实就是个二进制文件 RBD文件通过SAVE BGSAVE进行创建, SAVE会阻塞服务器进程,如果执行的话,那么client在这个期间发出的请求都不会响应 BGSAVE其实是创建fork出一个子进程来执行,其实本质他们都是在实行rdbsave 因为AOF的频率比RDB的频率高,所以启动服务器的时候,我们遵循着下面的原则 如果执行BGSAVE的时候,收到了save会被拒绝,因为他们都是执

redis学习之——持久化RDB 和AOF

RDB: 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里.rdb 保存的是dump.rdb文件 RDB工作原理: Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件.整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方,式要比AOF方式更加