Redis持久化介绍

Redis持久化:
Redis提供了多种不同级别的持久化方式:
1)RDB持久化可以在指定的时间间隔内生成数据集的时间点快照。
2)AOF持久化记录服务器执行的所有写存在命令,并在服务器启动时,并在服务器启动时,重新执行这些命令来还原数据。AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
3)Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
当然,我们也可以关闭redis的持久化功能,如果其中的数据并不重要的话。
 
RDB的优缺点:
优点:
1)RDB是一个非常紧凑的文件,保存了Redis在某一个时间点上的数据集。
2)RDB很适用于灾难恢复:它只有一个文件,并且内容紧凑,可以传输到其它数据中心
3)RDB可以最大化Redis的性能:Redis RDB持久化的方式是fork一个子进程,来处理所有的保存工作,不影响父进程的运行。
4)RDB恢复大量数据的效率比AOF数据恢复要快很多。
缺点:
1)RDB数据持久化有一个时间间隔,如果在这个时间间隔中发生了故障,将会丢失这一个时间段的数据。
2)在每次保存RDB时,redis都要fork一个子进程,来进行实际的持久化工作。如果数据集特别庞大的情况下,服务器可以会在有限的时间段中停止处理客户端的请求。(一般不会超过一秒)
 
AOF的优缺点:
优点:
1)AOF持久化让Redis变得更加耐久,我们可以设置不同的fsync策略(每秒钟一次,数据写入时fsync),默认一秒钟一次,但是这种时间间隔的话,和RDB一样存在数据丢失的情况。
2)AOF是一个只进行追加的日志文件,所以对于AOF文件的写入不需要seek。(即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题)
3)Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为redis只有在重写的文件完成之后,才会删除就的文件。
4)AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。
缺点:
1)对于相同的数据集来说,AOF文件的体积一般要大于RDB文件。
2)AOF的速度会慢于RDB。
3)AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。
 
持久化方案选择:
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
未来redis可能会将两种方案进行整合,但这并不是一个短期的事情。
 
RDB快照:
默认情况下,redis将数据库快照保存为dump.rdb文件。
你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。
你也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 进行数据集保存操作。
 
快照运作方式:
Redis保存快照的方式:
1)Redis使用fork创建子进程
2)子进程将数据集写入到临时RDB文件中
3)完成临时文件的写入之后,用其替换旧的RDB快照
 
AOF重写:
因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。
举个例子, 如果你对一个计数器调用了 100 次 INCR key , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。
然而在实际上, 只使用一条 SET key value [EX seconds] [PX milliseconds] [NX|XX] 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。
为了处理这种情况, Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。
执行 BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。
Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4 则可以自动触发 AOF 重写, 具体信息请查看 2.4 的示例配置文件。
 
AOF耐久性:
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。
有三个选项:
1)每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
2)每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
3)从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
如果不是对于数据可靠性有很强的要求,不推荐使用每次fsync的策略。
 
AOF错误处理:
服务器可能在程序正在对 AOF 文件进行写入时停机, 如果停机造成了 AOF 文件出错(corrupt), 那么 Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。
当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:
1)为现有的 AOF 文件创建一个备份。
2)使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复。
$ redis-check-aof --fix
3)(可选)使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处。
4)重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。
 
AOF重写运作方式:
1)Redis使用fork创建子进程
2)子进程将新的AOF文件写入到临时文件
3)对于新执行的写入命令,父进程将其保存在内存缓存的同时,将其追加到现AOF文件的末尾,保存AOF文件的可靠性。
4)子进程完成重写之后,告诉父进程,将内存缓存中的数据写入到新的AOF文件中
 
RDB 和 AOF 之间的相互作用
2.4之后 的 Redis 中, BGSAVE 执行的过程中, 不可以执行 BGREWRITEAOF 。 反过来说, 在 BGREWRITEAOF 执行的过程中, 也不可以执行 BGSAVE 。这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。
如果 BGSAVE 正在执行, 并且用户显示地调用 BGREWRITEAOF 命令, 那么服务器将向用户回复一个 OK 状态, 并告知用户, BGREWRITEAOF 已经被预定执行: 一旦 BGSAVE 执行完毕, BGREWRITEAOF 就会正式开始。
当 Redis 启动时, 如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集, 因为 AOF 文件所保存的数据通常是最完整的。
 
其余:
建议为Redis添加数据备份,定时复制RDB或者AOF文件,保存在自己的数据中心,同时,自动删除旧的备份文件。
 
作者:红雨
出处:https://www.cnblogs.com/52why
微信公众号: 红雨python
原文地址:https://www.cnblogs.com/52why/p/14357812.html