redis 持久化

Redis提供了RDB 和 AOF两种持久化方式。Redis允许两者结合,也允许两者同时关闭,让数据只在服务器运行时存在。

快照持久化RDB(Redis DataBase)

RDB持久化可以在指定的时间间隔内将内存中的数据集的快照(point-in-time snapshot)写入到本地的磁盘。

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

Redis会单独创建(fork)一个子进程来进行持久化:先将数据写入到一个临时RDB文件中,待子进程完成对新RDB文件的写入时,Redis用新RDB文件替换并删除旧的RDB文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

  • 优势
    适合大规模的对数据完整性和一致性要求不高的数据恢复
  • 劣势
    在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。

可以对Redis进行设置,让它在"N秒内数据集至少有M个改动"这一条件被满足时, 自动保存一次数据集;也可以通过调用SAVE或者BGSAVE手动让Redis进行数据集保存操作。

日志持久化AOF(Append Only File)

AOF以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录)。默认情况下AOF是保存在appendonly.aof文件中的,该文件只许追加但不可以改写。redis启动之初会读取该文件重新构建数据。换言之,redis重启的话可以根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

AOF特点:

  • AOF文件是一个只进行追加的日志文件
  • AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容不仅非常容易读懂,而且非常容易分析
  • Redis可以在AOF文件体积变得过大时,自动在后台对AOF文件进行重写
  • 对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积
  • 根据所使用的fsync策略,AOF的速度可能会慢于RDB

fsync三种策略

  • always:Redis每执行一条命令,都会写入到AOF文件中
  • everysec:Redis每隔一秒才把执行的命令写到AOF文件
  • no:

三种策略对比:
在这里插入图片描述

AOF重写
AOF重写就是把AOF中重复的、过期的、没有用的命令进行合并和删除。
AOF采用文件追加方式,文件会越来越大,为避免出现这种情况,新增了重写(rewrite)机制。当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩机制,只保留可以恢复数据的最小指令集。

AOF通过重写机制,可以减少硬盘占用量,加速恢复速度。
重写可以使用命令bgrewriteaof实现,其实现原理是:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),具体做法是:遍历新进程的内存中数据,每条记录有一条Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。

RDB与AOP比较

RDB持久化方式能够在指定的时间间隔内对数据进行快照存储;AOF持久化方式记录每次对服务器的写操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。AOF命令按redis协议追加保存每次写操作到文件末尾。Redis能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。分开来说如下所示:

  • RDB的优点:
    RDB是一个非常紧凑(compact)的文件,它保存了Redis在某个时间点上的数据集。这种文件非常适合用于进行备份,比如说:可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
    RDB非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容非常紧凑,可以(在加密后)将它传送到别的数据中心。RDB可以最大化Redis的性能:父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/O操作。RDB在恢复大数据集时的速度比AOF的恢复速度要快。

  • RDB的缺点:
    RDB不适合在服务器故障尽量不丢失数据的情况:虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。比如,在5分钟保存一次RDB文件的情况下,一旦发生故障停机, 就可能会丢失好几分钟的数据。
    每次保存RDB的时候,Redis都要fork()出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时,fork()可能会非常耗时,造成服务器在某某毫秒内停止处理客户端请求;如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。虽然AOF重写也会进行fork(),但无论AOF重写的执行间隔有多长,数据的耐久性都不会有任何损失。
    如果Redis data非常大,持久化RDB非常耗时、耗性能:
    不能保证Redis宕机时数据不丢失:

  • AOF的优点:
    使用AOF持久化会让Redis变得非常耐久(much more durable):可以设置不同的fsync策略,比如无fsync,每秒钟一次fsync,或者每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,Redis仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据(fsync会在后台线程执行,所以主线程可以继续努力地处理客户端的命令请求)。
    AOF文件是一个只进行追加操作的日志文件(append only log),因此对AOF文件的写入不需要进行seek,即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满、写入中途停机等等),redis-check-aof工具也可以轻易地修复这种问题。
    Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写:重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。
    AOF 文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单: 举个例子, 如果你不小心执行了FLUSHALL命令, 但只要AOF文件未被重写,那么只要停止服务器, 移除AOF文件末尾的FLUSHALL命令,并重启Redis,就可以将数据集恢复到FLUSHALL执行之前的状态。

  • AOF的缺点:
    对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积。根据所使用的fsync策略,AOF的速度可能会慢于RDB。在一般情况下,每秒fsync的性能依然非常高,而关闭fsync可以让AOF的速度和RDB一样快,即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB可以提供更有保证的最大延迟时间(latency)。
    AOF在过去曾经发生过这样的bug: 因为个别命令的原因,导致AOF文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令brpoplpush就曾经引起过这样的bug),测试套件里为这种情况添加了测试:它们会自动生成随机的、复杂的数据集,并通过重新载入这些数据来确保一切正常。虽然这种bug在AOF文件中并不常见,但是对比来说,RDB几乎是不可能出现这种bug的。

总的来说,相同数据集的数据而言,aof文件要远大于rdb文件,恢复速度慢于rdb。aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。

如果只希望数据在服务器运行的时候存在,可以不使用任何持久化方式。
一般来说,如果想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。当RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。
如果可以承受数分钟以内的数据丢失(对数据的完整度要求不高),那么可以只使用RDB持久化。
不推荐只使用AOF持久化,原因是定时生成RDB快照(snapshot)非常便于进行数据库备份(AOF在不断变化不好备份),并且RDB恢复数据集的速度也要比AOF恢复的速度快,除此之外,使用RDB还可以避免之前提到的AOF程序的bug。

启用AOF的好处是在最恶劣情况下也只会丢失不超过两秒的数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率:AOF重写的基础大小默认值64M太小了,可以设到5G以上;默认超过原大小100%大小时重写可以改到适当的数值。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>