Redis 的落地策略

Redis 的落地策略其实就是持久化(Persistence),主要有以下2种策略:

  1. RDB: 定时快照方式(snapshot)
  2. AOF: 基于语句追加文件的方式

RDB

RDB 文件非常紧凑,它保存了 Redis 某个时间点上的数据集。RDB 恢复大数据集时速度要比 AOF 快。但是 RDB 不适合那些对时效性要求很高的业务,因为它只保存了快照,在进行恢复时会导致一些时间内的数据丢失。实际在进行备份时,Redis 主要依靠 rdbSave() 函数,然后有两个命令会调用这个函数 SAVEBGSAVE,前者会同步调用,阻塞主进程导致会有短暂的 Redis-server 停止工作,后者会 fork 出子进程异步处理。

在调用 SAVE 或者 BGSAVE 时,只有发布和订阅功能的命令可以正常执行,因为这个模块和服务器的其他模块是隔离的。
下面的命令表示: “60 秒内有至少有 1000 个键被改动”时进行RDB文件备份。

redis-server> SAVE 60 1000

RDB 文件的结构

开头的REDIS表示这是一个 RDB 文件,然后紧跟着 redis 的版本号,SELECT-DBKEY-VALUES-PAIRS 构成了对一个数据库中的所有数据记录,其中 KEY-VALUES-PAIRS 具体结构如下,后面两个就不用说了。

其中对于不同的类型,RDB文件中有不同的 layout,具体就不写出来了。

AOF

AOF 可以通过设置的 fsync 策略配置,如果未设置 fsync ,AOF 的默认策略为每秒钟 fsync 一次,在这种配置下, fsync 会在后台线程执行,所以主线程不会受到打扰。但是像 AOF 这种策略会导致追加的文件非常大,而且在恢复大数据时非常缓慢,因为要把所有会导致写数据库的命令都重新执行一遍。AOF文件中实际存储的是 Redis 协议下的命令记录,因此非常易读。

当然 Redis 考虑到了 AOF 文件过大的问题,因此引入了 BGREWRITEAOF 命令进行重建 AOF 文件,保证可以减少大量无用的重复写操作。重建命令并不会去分析已有的 AOF 文件,而是将当前数据库的快照保存。

在 AOF 文件重写时,Redis 的具体逻辑如下:

  1. Redis 首先 fork 出一个子进程,子进程将新 AOF 文件的内容写入到临时文件。
  2. 对于所有新执行的写入命令,父进程一边将它们累积到一个缓存中,一边将这些改动追加到现有 AOF 文件的末尾: 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
  3. 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将缓存中的所有数据追加到新 AOF 文件的末尾。
  4. 现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。

Redis 会维持一个默认的AOF重写策略,当当前的AOF文件比上次重写之后的文件大小增大了一倍时,就会自动在后台重写AOF。

posted on 2018-07-24 22:29  daghlny  阅读(4930)  评论(0编辑  收藏  举报

导航