我们之前介绍了 Redis 五种数据类型的命令 与 配置文件的基本配置 ,今天让我们从理论和配置两个层面来揭开 Redis 持久化的神秘面纱。

公司主营业务:成都网站制作、成都网站设计、外贸营销网站建设、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出宣州免费做网站回馈大家。
所谓持久化可以简单理解为将内存中的数据保存到硬盘上存储的过程。持久化之后的数据在系统重启或者宕机之后依然可以进行访问,保证了数据的安全性。
Redis 有两种持久化方案,一种是快照方式( SNAPSHOTTING ),简称 RDB ;一种是只追加模式( APPEND ONLY MODE ),称为AOF。接下来让我们分别了解一下它们的使用与注意事项。
RDB 为 Redis DataBase 的缩写,是 Redis 默认的持久化方案。它能够在指定的时间间隔内将内存数据集快照( snapshot )写入磁盘,恢复时将快照文件( dump.rdb )读回内存。
我们先来扒一下配置文件中的 SNAPSHOTTING :
在给定的 秒数 内,如果对数据库执行的 写入操作数 达到设定的值,则将数据同步到数据文件。支持多个条件配合, Redis 默认配置文件中提供了三个条件:
- save 900 1 //900s内有1个更改
- save 300 10 //300s内有10个更改
- save 60 10000 //60s内有10000次更改
注意:若不想用 RDB 方案,可以把 save "" 的注释打开,上边三个注释掉。
当 bgsave 出现错误时, Redis 是否停止执行写命令;
yes ,则当硬盘出现问题时, Redis 将停止接受写入操作,这样我们可以及时发现,避免数据的大量丢失;
- no
- Redis
- bgsave
如果已经设置了对 Redis 服务器的正确监视和持久性,即采用了其他手段发现和控制数据完整性,可能希望禁用此功能,以便即使在磁盘、权限等方面出现问题时, Redis 仍能正常工作。
注意:如果后台保存过程将再次开始工作, Redis 将自动允许再次写入。
指定存储到本地数据库时是否 压缩 ( Redis 采用 LZF 压缩)数据,默认为 yes 。如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变得巨大。
从 RDB 版本 5 开始,在存储快照后,还可以使用 CRC64 算法来进行数据校验, CRC64 校验放在文件的末尾。开启之后,保存和加载 RDB 文件时会增加大约 10% 的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
禁用 校验和 创建的 RDB 文件的校验和为零,这将告诉加载代码跳过检查。
指定本地数据库文件名,重启之后自动加载进 内存 ,手动执行 save 命令的话即刻生效。
大坑请注意: flushall 、 shutdown 命令都会清空并提交至 dump.rdb
指定本地数据库存放目录。
- Redis
- dump.rdb
- fork()
RDB 中;
- RDB
- Redis
- RDB
- RDB
- RDB
这种工作方式使得 Redis 可以从写时复制( copy-on-write )机制中获益。
配置文件中默认的快照配置;
save (阻塞, 只管保存快照,其他的等待)或者是 bgsave (异步)命令,快照同时还可以响应客户端命令;flushall 命令,清空数据库所有数据,意义不大;shutdown 命令,保证服务器正常关闭且不丢失任何数据,意义也不大。在实际开发中,一般会考虑到物理机硬盘损坏的情况,所以我们会选择备份 dump.rdb 文件。将备份的 dump.rdb 文件拷贝到 redis 的安装目录的 bin 目录下,重启 redis 服务即可。
RDB 是一个非常紧凑的文件,非常适用于数据集的备份;RDB 是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复;Redis 的主进程不进行 I/O 操作,确保了极高的性能;RDB 比 AOF 方式更加高效。Redis 意外宕机时,你可能会丢失几分钟的数据;
- RDB
- fork
- fork
- Redis
- CPU
- AOF
- fork
为了解决 RDB 方式在宕机时丢失数据过多的问题,从 1.1 版本开始, Redis 增加了一种 durable 的持久化方式: AOF 。
AOF 是 Append Only File 的缩写,默认不开启。 AOF 以日志的形式来记录每个写操作,只允许追加文件但不可以改写文件,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
我们再来看一下配置文件中的 APPEND ONLY MODE :
默认为关闭状态,改为 yes 打开持久化。 AOF 和 RDB 可以同时启用而不会出现问题。
文件默认名称,启动即创建。加载 先于 dump.rdb 文件
同步策略:系统函数 fsync() 告诉操作系统在磁盘上实际写入数据。 Redis 支持三种不同的模式
- appendfsync always //每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好
- appendfsync everysec //默认推荐,异步操作,每秒记录,如果宕机,有1秒内数据丢失
- appendfsync no //不同步,只有在操作系统需要时在刷新数据
要想了解接下来的配置内容,先得说一下“日志重写”的原理:
由于 AOF 采用的是将命令追加到文件末尾的方式,所以随着写入命令的不断增加, AOF 文件的体积会变得越来越大。为避免出现此种情况,新增了重写机制:可以在不打断服务客户端的情况下,对 AOF 文件进行重建( rebuild )。
重写触发:通过执行 bgrewriteaof 命令,可以生成一个新的 AOF 文件,该文件包含重建当前数据集所需的 最少 命令。 Redis 2.2 需手动执行该命令, Redis 2.4 则可以通过修改配置文件的方式自动触发(配置在下边涉及)。
Redis 执行系统函数 fork() ,创建一个子进程(与主进程完全一致);AOF 文件的内容写入到临时文件;AOF 文件的末尾,这样即使在重写的中途发生停机,现有的 AOF 文件也是安全的;AOF 文件的末尾。Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。当我们同时执行主进程的 写操作 和子进程的 重写 操作时,两者都会操作磁盘,而重写往往会涉及到大量的磁盘操作,这样就会造成主进程在写 aof 文件的时候出现阻塞的情形。
为了解决这个问题, no-appendfsync-on-rewrite 参数出场了。
no ,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题;
- yes
- appendfsync
- no
- redis
- linux
因此,如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为 yes ;如果应用系统无法忍受数据丢失,则设置为 no 。
重写百分比,默认为上次重写后 aof 文件大小的一倍。
重写触发的最小值:64mb。
根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。 Redis 会记录上次重写时的 AOF 大小,默认配置是当 AOF 文件大小是上次 rewrite 后大小的一倍且文件大于 64M 时触发。
大型互联网公司一般都是 3G 起步
当 AOF 文件被截断时,即 AOF 文件的最后命令不完整,如果此时启动 Redis ,会将 AOF 数据加载回内存,此时便会出现问题。
AOF , Redis 服务器开始发出日志,通知用户该事件;no:服务器将中止并出现错误,拒绝启动。
当我们得知 AOF 文件报错时,可以用以下方法来修复出错的 AOF 文件:
为现有的 AOF 文件创建一个备份;
使用 Redis 附带的 redis-check-aof 命令,对原来的 AOF 文件进行修复;
redis-check-aof –fix
redis-check-aof --fix appendonly.aof 修复命令,杀光不符合规范的语法
( 可选 )使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处;
重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。
在重写 AOF 文件时, Redis 能够在 AOF 文件中使用 RDB 前导,以加快重写和恢复速度。启用此选项后,重写的 AOF 文件由两个不同的节组成: RDB file 、 AOF tail
加载 Redis 时,会识别 AOF 文件以 Redis 字符串开头,并加载带前缀的 RDB 文件,然后继续加载 AOF 尾部。
AOF 的持久化通过使用不同的策略,最多丢失1秒的数据;AOF 文件是一个只进行追加的日志文件,不需要写入 seek ;
- Redis
- AOF
- AOF
AOF 文件记录的写入操作以 Redis 协议的格式保存,容易读懂,容易对文件进行分析;AOF 文件的体积通常要大于 RDB 文件的体积;
- fsync
- AOF
- RDB
在一般情况下,每秒 fsync 的性能依然非常高,而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。不过在处理巨大的写入载入时, RDB 可以提供更有保证的最大延迟时间( latency )。
一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性,应该同时使用两种持久化功能。
如果非常关心数据,但仍然可以承受数分钟以内的数据丢失,那么可以只使用 RDB 持久化。
由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此 AOF 是目前 主流 的持久化方式。
有很多用户都只使用 AOF 持久化,但我们并不推荐这种方式:因为定时生成 RDB 快照( snapshot )非常便于进行数据库备份,并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。
在版本号大于等于 2.4 的 Redis 中, BGSAVE 执行的过程中,不可以执行 BGREWRITEAOF 。反过来说,在 BGREWRITEAOF 执行的过程中,也不可以执行 BGSAVE 。这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。
如果 BGSAVE 正在执行,并且用户显示地调用 BGREWRITEAOF 命令,那么服务器将向用户回复一个 OK 状态, 并告知用户 BGREWRITEAOF 已经被预定执行:一旦 BGSAVE 执行完毕, BGREWRITEAOF 就会正式开始。
当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。
- cron job
- RDB
- RDB
find 命令来删除过期的快照;RDB 备份到你的数据中心之外,或者至少是备份到你运行 Redis 服务器的物理机器之外。在实际应用时,因为 RDB 文件只用作后备用途,建议只在 slave 上持久化 RDB 文件,而且只需要15分钟备份一次就够了,只保留 save 900 1 这条规则。
如果开启 AOF ,好处是在最恶劣情况下也只会丢失不超过2秒数据,启动脚本较简单只 load 自己的 AOF 文件就可以了。代价一是带来了持续的 IO ,二是 AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。
只要硬盘许可,应该尽量减少 AOF rewrite 的频率, AOF 重写的基础大小默认值 64M 太小了,可以设置到 5G 以上。默认超过原大小的100%时重写可以改到适当的数值。
如果不开启 AOF ,仅靠 Master-Slave Replication 实现高可用性也可以。能省掉一大笔 IO ,也减少了 rewrite 时带来的系统波动。代价是如果 Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB 文件,载入较新的那个。