赞
踩
redis的持久化指将数据写入可靠内存中,如ssd。Redis提供了4种持久化策略
一般情况下,如果你希望有PostgreSql一样的数据安全性的话,你应该两种都使用。
如果你很关心你的数据,但是可以忍受几分钟的数据丢失的话,可以单独使用RDB。
很多用户单独使用AOF,但是我们不建议这样做。因为用RDB做数据备份、快速启动恢复很好,也可以防止AOF引擎出现错误。
默认情况下,RDB将数据集快照存储在磁盘上的dump.rdb文件中。你可以设置rdb在至少有M个key发生变化时每N秒保存一次,或者可以使用save或bgsave命令手动调用保存。
例如,这个命令表示如果至少有1000个key发生变化,每60秒保存一次
save 60 1000
实现原理
这种方法可以让redis使用写时复制技术。
写时复制指的是对于一个文件对象,不同的进程映射到虚拟地址空间的都是同一个物理内存,只有某个进程试图修改数据时,才会在物理内存中拷贝一份数据。
快照并不是很可靠。如果你的redis服务停止了,或者断电了,或者你不小心杀掉了进程,那么最近的数据就会丢失。虽然对某些应用来说问题不大,但是有些应用却不能接受,所以单独使用RDB不得行。
AOF是一个完全可靠的持久化方案,在1.1版本中推出。
你可以在配置文件中打开AOF
appendonly yes
现在开始,每次redis接收到一个写指令的时候都会追加到aof文件中。当你重启redis的时候就会重新执行aof文件来恢复到之前的状态。
从7.0开始,redis使用多个aof文件机制。原来的一个aof文件会分割为一个base文件(最多一个)和incremental文件(增量文件,可能有多个)。base文件代表重写时的最初的数据集快照,增量文件保存了base文件创建之后追加的指令。这些文件分布在不同的目录下并且被manifest文件追踪。
随着写操作的增加,aof文件会越来越大。比如我们执行了100次的自增操作,那么redis中只有一个key,但是aof中有100条指令。其中99条都是无用的。
重写过程是绝对安全的。在重写时redis会持续写入旧文件,并根据当前数据集创建一个最小指令的新文件。一旦新文件准备就绪,redis就会切换两个文件,并在开始在新文件后追加指令。
所以redis提供一个有趣的特性:它能够在后台重写AOF而不中断对客户端的服务。当你执行bgrewriteaof命令时,redis会根据当前数据集创建一个最小化的aof文件。如果你使用的是2.2版本,那么你需要时不时的调用bgrewriteaof。从2.4开始redis会自动重写aof。
从7.0版本开始,当AOF重写被调度的时候,父进程会开启一个增量文件并将接下来的指令写入进去,子进程会执行重写逻辑并生成一个新的base文件。redis会用临时的manifest文件来追踪新创建的base和增量文件。当这些文件准备好的时候,redis会执行一个原子性的替换操作来让临时manifest文件生效。为了避免在AOF重写重复失败和重试时创建许多增量文件的问题,Redis引入了AOF重写限制机制,以确保以越来越慢的速度重试失败的AOF重写。
你可以设置fsync的策略,有3种模式:
推荐的和默认的模式是每秒同步。速度和安全性都有保障。always策略在实践表现很慢,但是支持分组提交,redis会执行单次fsync。
这可能发生在重写时redis崩溃,或者重写时aof文件所在的磁盘满了。当这种情况发生时,AOF仍然包含表示数据集的给定时间点版本的一致数据(使用默认AOF fsync策略,该数据集可能早到一秒),但AOF中的最后一个命令可能会被截断。Redis的最新主要版本无论如何都可以加载AOF,只需丢弃文件中最后一个格式不正确的命令即可。在这种情况下,服务器将发出如下日志:
* Reading RDB preamble from AOF file...
* Reading the remaining AOF tail...
# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 439 !!!
# AOF loaded anyway because aof-load-truncated is enabled
如果aof文件的字节序列在中间发生错误,情况会比truncate更复杂。redis会在启动时报出:
* Reading the remaining AOF tail...
# Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>
最好的办法是运行redis-check-aof,不使用–fix选项。然后分析问题,找到给出的文件offset处,并查看是否可以手动修复aof文件:aof文件使用和redis一样的协议,很容易理解和修复。否则可以让工具为我们修复,但是这可能丢失从错误开始到文件结尾的部分,如果错误发生在很靠前的位置,可能丢失大量的数据。
aof重写和快照一样使用了写时复制技术:
这个问题在2.2之前和之后的版本不一样,可以理解为2.2版本之后更简单且完全不需要重启。
第一条命令打开aof
第二条命令关闭快照持久化,这个命令的是可选的,如果你希望使用两种策略的话。
PS:不要忘记修改配置文件,否则重启之后上面的配置会失效并依然使用旧的配置文件中的配置。
redis以后的版本会避免rdb执行期间触发aof重写,或者在aof重写时使用bgsave保存rdb。这可以避免redis的后台进程执行过重的磁盘I/O。
当后台正在执行rbd快照保存,用户明确使用bgrewriteaof指令时,服务会返回ok告诉用户重写操作已加入调度,一旦rdb完成就会立刻执行aof。
如果AOF和RDB都打开了,redis重启时会使用aof来重新构建数据,因为aof能保证数据更完整。
redis的备份功能很友好,因为redis运行时可以复制rdb文件:rdb一旦创建就不会再更改,新的rdb会保存再临时文件里,新的文件准备就绪时就会原子性的重命名为旧的文件名。
这意味这redis运行时复制rdb文件是安全的,我们建议:
如果你的redis只使用了aof,也可以备份。7.0开始,aof分为多个文件,这些文件保存在appenddirname配置的目录下。通常情况下你需要做的就是复制或者打包这些文件作为备份。使用这种方式备份要确保备份时关闭aof重写:
CONFIG SET auto-aof-rewrite-percentage 0
INFO persistence
aof_rewrite_in_progress
为0,如果为1意味着正在重写,需要等一会CONFIG SET auto-aof-rewrite-percentage <prev-value>
原文档:redis持久化
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。