Redis持久化

350 阅读7分钟

Redis Persistence

Redis provides a different range of persistence options:

  • The RDB persistence performs point-in-time snapshots of your dataset at specified intervals.
  • The AOF persistence logs every write operation received by the server, that will be played again at server startup, reconstructing the original dataset. Commands are logged using the same format as the Redis protocol itself, in an append-only fashion. Redis is able to rewrite the log in the background when it gets too big.
  • If you wish, you can disable persistence completely, if you want your data to just exist as long as the server is running.
  • It is possible to combine both AOF and RDB in the same instance. Notice that, in this case, when Redis restarts the AOF file will be used to reconstruct the original dataset since it is guaranteed to be the most complete.

RDB(Redis Database)

是什么?

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

Fork

fork的作用是复制一个与当前进程一样的进程,新进程的所有数据(变量、环境变量、程序计数器等)数值都原进程一致,但是是一个全新的进程,并作为原进程的子进程。

RDB保存的文件是dump.rdb

如何触发RDB快照

  • 可以通过命令行中save,bgsave(区别于save, 后台进行备份,不会阻塞前台服务)或者flushall(只会产生一个空的dump.rdb)进行实时触发,
  • 也可以通过修改配置文件中save 进行自动触发。

如何恢复

将备份文件dump.rdb移动到redis安装目录并启动服务既可以

优势和劣势

  • 优势:
    • 适合大规模的数据恢复
    • 对数据完整性和一致性要求不高
  • 劣势:
    • 在一定间隔时间做一次备份,如果redis意外down掉了,就回丢失最后一次快照后的数据
    • fork的时候,内存中的数据被克隆一份,大致2倍的膨胀性需要考虑

如何停止

动态停止RDB保存规则的方法:redis-cli config set save ""

总结

  • RDB是一个非常紧凑的文件
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来完成,父进程不需要再做其他的IO操作,所以RDB持久化的方式可以最大化Redis的性能
  • 与AOF相比,在恢复大的数据集的时候,RDB方式更快一些
  • 数据丢失风险大
  • RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较的大时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级不能响应客户端的请求

AOF(Append Only File)

是什么

以日志的形式来记录每个写操作,将redis执行过的所有写指令记录下来,只许追加文件但不可以改写文件,redis启动之初会读取改文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据恢复的工作。

AOF保存

appendonly.aof

AOF启动/修复/恢复

  • 正常恢复
    • 启动,将appendonly修改为yes,默认值为no
    • 将数据的aof文件复制一份保存到对应目录(config get dir)
    • 恢复,重启redis然后重新加载
  • 异常恢复
    • 启动,设置yes
    • 备份写坏的aof文件
    • 修复,redis-check-aof --fix appendonly.aof 进行修复
    • 恢复,重启redis然后重新加载

Rewrite

  • 简介:AOF采用文件追加方式,文件会越来越大为了避免出现这种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof触发。
  • 原理:AOF文件持续增长而过大时,会fork出一条新进程来讲文件重写(也就是先写临时文件最后在rename),便利新进程的内存数据,每条记录有一个set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
  • 触发机制:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。

强制写入磁盘的策略及特点

  • appendfsync always: 每次发生数据更新会立即记录到磁盘,性能差但数据完整性比较好
  • appendfsync everysec: 每秒同步,性能有较好,但如果一秒内宕机,可能丢失数据
  • appendfsync no: 不开启强制同步,交给OS决定何时同步,性能更好,但一旦宕机,就可能丢失大量数据

劣势

  • 相同数据集的数据而言aof文件要远大于rdb文件,恢复速速鳗鱼rdb
  • AOF运行效率要慢于RDB,每秒同步策略效率较好,不同步效率和RDB相同

总结

  • AOF文件是一个只进行追加的日志文件
  • Redis可以在AOF文件体积变得过大时,自动在后台对AOF进行重写
  • 对于相同的数据集,AOF文件的体积通常要大于RDB文件的体积
  • 根据所使用的的fsync策略,AOF的速度可能会慢于RDB

总结(官网建议)

  • RDB持久化方式能够在指定时间间隔内对你的数据进行快照存储
  • AOF持久化方式记录每一次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis的协议追加保存每次写得操作到文件末尾
  • Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  • 只能做缓存,如果你只希望你的数据在服务器运行时存在,你也可以不使用任何方式持久化
  • 同时开启两种持久化方式,在这种情况下,当redis重启的时候回优先载入AOF文件来恢复原始数据,因为在通常情况下AOF文件保存的数据要比RDB文件保存的数据要完整。RDB的数据不实时,同时使用两者时服务器重启也会只找AOf文件。要不要只使用AOF呢,不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份)。
  • 性能建议:
    • RDB文件只用作后备用途,建议只在slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留sava 900 1这条规则。
    • 如果enable aof,好处是在最恶劣的情况下只会丢失不超过两秒的数据,启动脚本简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最好将rewrite过程中产生新的数据写到新文件造成的阻塞几乎不可毕淼的,只要硬盘许可,应该尽量少AOF rewrite的频率,AOF重写的基础大小默认值为64M太小,可以设到5G以上,默认超过原来的100%时重写可以改到适当的值。
    • 如果不enable aof,仅靠Master-Slave Relication实现高可用姓也可以。能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同事挂掉,会丢失十几分钟的数据,启动脚本比较两个Master/Slave中的RDB文件,载入较新的哪一个。