redis -- RDB

Redis 分别提供了 RDB 和 AOF 两种持久化模式。

在 Redis 运行时,RDB 程序将当前内存中的数据库快照保存到磁盘文件中,在 Redis 重启动

时,RDB 程序可以通过载入 RDB 文件来还原数据库的状态。

RDB功能最核心的是rdbSave 和rdbLoad 两个函数,前者用于生成RDB文件到磁盘,

而后者则用于将RDB文件中的数据重载内存中。

保存

rdbSave函数负责内存中的数据以RDB格式保存到磁盘,

如果RDB文件已经存在,则替换现有文件。

在保存RDB文件期间,主进程会被阻塞,直到保存完成为止

save和bgsave调用方式区别

  • SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。

    • 在主进程阻塞期间,服务器不能处理客户端的任何请求
  • BGSAVE 则 fork 出一个子进程,子进程负责调用 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

  • 当 SAVE 执行时,Redis 服务器是阻塞的,

    • 所以当SAVE正在执行时,新的SAVE、BGSAVE或BGREWRITEAOF调用都不会产生任何作用。
  • 因为 AOF 写入由后台线程完成,而 BGREWRITEAOF 则由子进程完成
    • 所以在 SAVE执行的过程中,AOF 写入和 BGREWRITEAOF 可以同时进行
    • 只是新的AOF 不产生作用,原来已存在

BGSAVE

  • 在执行 SAVE 命令之前,服务器会检查 BGSAVE 是否正在执行当中,

    • 如果是的话,服务器就不调用rdbSave,而是向客户端返回一个出错信息,告知在BGSAVE执行期间,不能行SAVE。
    • 避免 SAVE 和 BGSAVE 调用的两个 rdbSave 交叉执行,造成竞争条件
  • 当 BGSAVE 正在执行时,调用新 BGSAVE 命令的客户端会收到一个出错信息,告知 BGSAVE 已经在执行当中。
  • BGREWRITEAOF 和 BGSAVE 不能同时执行
    • 两个命令并没有什么冲突的地方不能同时执行它们只是一个性能方面的考虑

载入

  • 当 Redis 服务器启动时,rdbLoad 函数就会被执行,它读取 RDB 文件,并将文件中的数据库数据载入到内存中。
  • 在载入期间,服务器每载入 1000 个键就处理一次所有已到达的请求,
    • 不过只有PUBLISH、SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE 会被正确地处理,

      • 发布与订阅功能和其他数据库功能是完全隔离的
      • 所以在服务器载入期间,订阅与发布功能仍然可以正常使用
    • 其他命令一律返回错误。
  • 因为 AOF 文件的保存频率通常要高于 RDB 文件保存的频率,一般AOF文件中的数据会比 RDB 文件中的数据要新
    • 因此,如果服务器在启动时,打开了 AOF 功能,那么程序优先使用 AOF 文件来还原数据
    • 只有在 AOF功能未打开的情况下,Redis 才会使用 RDB 文件来还原数据。

RDB文件结构



  • REDIS

    • 文件开头保存着redis五个字符,标识着一个RDB文件的开始
  • RDB-VERSION
    • 记录该文件所使用的RDB版本号
    • 不同版本的RDB文件互不兼容,
      • 程序读取时,需要根据不同版本号选择不同读入方式
  • DB-DATA
    • 这个部分在一个 RDB 文件中会出现任意多次

      • 每个 DB-DATA 部分保存着服务器上一个非空数据库的所有数据。
    • SELECT-DB
      • 数据库号码
    • KEY-VALUE-PAIRS
      • 因为空的数据库不会被保存到 RDB 文件,所以这个部分至少会包含一个键值对的数据
      • 每个键值对的数据使用以下结构来保存:
        • OPTIONAL-EXPIRE-TIME | TYPE-OF-VALUE | KEY | VALUE
        • OPTIONAL-EXPIRE-TIME
          • OPTIONAL-EXPIRE-TIME域是可选的,如果键没有设置过期时间,那么这个域就不会出现
          • 如果有,则是一个以毫秒为单位的Unix时间戳
        • TYPE-OF-VALUE
          • 记录着value域所使用的编码,根据这个编码,程序会使用不同的方式来保存和读取value值
        • KEY
          • 保存键值
        • VALUE
    • EOF
      • 标志着数据库内容的结尾(不是文件的结尾)
      • 值为 rdb.h/EDIS_RDB_OPCODE_EOF(255)
    • CHECK-SUM
      • RDB文件所有内容的校验和
      • 如果为0 ,那么表示redis关闭校验和功能

小结

  • rdbSave 会将数据库数据保存到 RDB 文件,并在保存完成之前阻塞调用者
  • SAVE 命令直接调用 rdbSave ,阻塞 Redis 主进程;BGSAVE 用子进程调用 rdbSave ,主进程仍可继续处理命令请求
  • SAVE 执行期间,AOF 写入可以在后台线程进行,BGREWRITEAOF 可以在子进程进行,所以这三种操作可以同时进行
  • 为了避免产生竞争条件,BGSAVE 执行时,SAVE 命令不能执行。
  • 为了避免性能问题,BGSAVE 和 BGREWRITEAOF 不能同时执行
  • 调用 rdbLoad 函数载入 RDB 文件时,不能进行任何和数据库相关的操作,不过订阅与发布方面的命令可以正常执行,因为它们和数据库不相关联。
  • RDB 文件使用不同的格式来保存不同类型的值
时间: 2024-10-29 19:09:34

redis -- RDB的相关文章

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

Redis RDB、 AOF 两种机制

二.RDB机制的优势和劣势: RDB存在哪些优势呢? 1). 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的.比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据.通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复. 2). 对于灾难恢复而言,RDB是非常不错的选择.因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上. 3). 性能最大化.对于Redis的服务进程而言,在开始持久

Redis RDB持久化异常

导致异常情况: 1.三个redis节点数据 无法rdb持久化 2.redis数据 只能读不能写入(有问题1导致),结果直接导致数据无法新增和更新 目前临时处理方式: 1. config set stop-writes-on-bgsave-error no   先让数据可以写redis,不影响线上数据的读写操作 2.调整  vm.overcommit_memory = 2 ,这个配置目前没有效果,因为redis主进程内存使用量已经较高 0 直接和空闲物理内存对比,足够就放行 1 直接放行 2 物理

redis RDB 和AOF

参考文献 Redis源码学习-AOF数据持久化原理分析(0) Redis源码学习-AOF数据持久化原理分析(1) Redis · 特性分析 · AOF Rewrite 分析 深入剖析 redis AOF 持久化策略 函数sync.fsync与fdatasync总结整理 redis是一个内存数据库,它将数据保存在自己的内存之中.这意味着如果机器宕机或者断电,将会导致内存中的数据失效.为了能让数据不会出现丢失的情况,redis提供了RDB和AOF两种持久化的功能.接下来讲分别介绍RDB和AOF的原理

[Redis] RDB & AOF

http://my.oschina.net/davehe/blog/174662 rdb - 存在dump.rdb 的二进制文件中 dump 整个db, 数据多的时候,不合适频繁保存,保存的时间间隔应该长一些 保存的数据文件紧凑,恢复大数据文件快 如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复. 父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作. RDB

redis rdb文件解析

http://www.ttlsa.com/python/redis-rdb-tools-analysis-of-reids-dump-file-and-memory-usage/ redis-rdb-tools:命令过滤/解析rdb文件 redis-memory-for-key:从内存中读取对应key值得信息,大小/类型等 SQLite:轻型数据库 SQLite 安装指南 http://blog.csdn.net/tianyou121/article/details/6104317

Redis持久化之rdb&aof

Redis有两种持久化的方式:快照(RDB文件)和追加式文件(AOF文件) RDB持久化方式是在一个特定的间隔保存某个时间点的一个数据快照. AOF(Append only file)持久化方式则会记录每一个服务器收到的写操作.数据回复时,这些记录的操作会逐条执行从而重建出原来的数据.写操作命令  记录的格式跟Redis协议一致,以追加的方式进行保存. Redis的持久化是可以禁用的,两种方式的持久化是可以同时存在的,但是当Redis重启时,AOF文件会被优先用于重建数据. 一.RDB RDB就

redis的 rdb 和 aof 持久化的区别

aof,rdb是两种 redis持久化的机制.用于奔溃后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个db dump保存下来.save, shutdown, slave 命令会触发这个操作.粒度比较大,如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复. aof有如下特性: Code: 把写操作指令,持续的写到一个类似日志文件里.(类似于从postgresql等数据库导

redis 系列16 持久化 RDB

原文:redis 系列16 持久化 RDB 一.概述 Redis是内存数据库,一旦服务器进程退出,服务器中的数据库内存数据状态也会消失.为了解决这个问题,Redis提供了RDB 持久化功能,这个功能可以将redis在内存中的数据库状态保存到磁盘中,避免数据意外丢失. RDB持久化可以手动执行,也可以根据服务器配置选项定期执行,是在指定的时间间隔,对你的数据进行快照存储.该RDB文件快照是一个经过压缩的二进制文件.文件名为dump.rdb,该文件保存在redis目录下,当redis服务器停机后,只