6-Redis 的持久化之 AOF

2017-01-01 16:42:13


该系列文章链接
NoSQL 数据库简介
Redis的安装及及一些杂项基础知识
Redis 的常用五大数据类型(key,string,hash,list,set,zset)
Redis 配置文件介绍
Redis 持久化之RDB
Redis 持久化之AOF
Redis 主从复制
Redis 事务
Redis 发布与订阅
Redis jdedis 介绍


Redis 官网介绍 持久化(RDB 与 AOF)
1.AOF: Append only file
AOF 以日志的形式记录每个写操作,将 Redis 执行过的所有写指令记录下来,不记录读操作。
只需追加文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,也就是说,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次已完成数据的恢复工作

aof 保存的文件是 appendonly.aof 文件

2.AOF 在 redis.conf 的一些配置
    2.1 appendonly
         默认情况下,Redis异步转储数据集到磁盘上。此模式在许多应用程序中都足够好,但例如如果Redis进程会由于停电的问题而导致几分钟的写入丢失(取决于配置的保存点)。
        AOF 是一种备用持久化模式,可提供更好的持久化。例如,使用默认数据 fsync 策略(请参阅配置文件中的后面部分)Redis在服务器断电等戏剧性事件中只会丢失一秒写入,如果Redis进程本身出现问题,则会丢失一次,但是操作系统仍然正常运行。
        可以同时启用AOF和RDB持久化以保证不会出现问题。
        如果在启动时启用AOF,Redis将加载AOF,即文件
        将具有更好的持久性保证。
        请查看 http://redis.io/topics/persistence 以获取更多信息。

总的来说,这个配置是 开启或关闭AOF 的总配置

2.2 appendfilename
        AOF 文件的名称(默认:"appendonly.aof")

2.3 appendfsync
         调用 fsync()将让操作系统实际写入数据到磁盘上,而不是等待输出缓冲区中的更多数据。某些操作系统会真正刷新数据到磁盘上,其他一些操作系统会尽快尝试这样做。
        Redis支持三种不同的模式:
            no:不要 fsync,只需让操作系统在需要时刷新数据。速度更快。
            always:每次有写入操作都会调用 fsync,将写入操作记录到 appendonly.aof 中。慢,最安全。
            everysec:每秒调用一次 fsync ,将写入操作记录到 appendonly.aof 中。妥协方案。

默认值为“everysec”,因为这通常是速度和数据安全之间的正确折衷。这取决于你是否可以理解不总是让操作系统在需要时刷新输出缓冲区,以获得更好的性能(但如果你能想到一些数据丢失的想法,请考虑默认的持久化模式,也就是 RDB),或相反,使用“always”,将非常慢,但比 everysec 方案更安全。
        更多详情请查看以下文章:http://antirez.com/post/redis-persistence-demystified.html

如果不确定,请使用“everysec”。
        
    2.4 no-appendfsync-on-rewrite
        当AOF fsync策略设置为always或everysec且后台保存进程(后台保存或AOF日志后台重写)正在对磁盘执行大量I/O操作时,在某些Linux配置中,Redis可能会阻塞太长时间在 fsync()调用。请注意,目前没有对此进行修复,因为即使在不同的线程中执行 fsync 也会阻塞我们的同步 write(2) 的调用。
        为了缓解这个问题,当BGSAVE或BGREWRITEAOF正在进行中时可以使用这个配置来阻止在主进程中调用fsync()。
        这意味着当另一个子进程正在保存时,Redis的 appendfsync 策略将会与“appendfsync none”相同。实际上,这意味着在最糟糕的情况下(使用默认的Linux设置)可能会丢失最多30秒的日志。
        如果您有延迟问题,请将其转为 "yes"。否则,从耐用性的角度来看,它是最“最安全”的选择使用 "no"。

2.5 auto-aof-rewrite-percentage/auto-aof-rewrite-min-size
        自动重写 appendonly.file 。
        当AOF日志大小增长到指定的百分比(即 auto-aof-rewrite-percentage的值)时,Redis能够自动重写日志文件,隐式调用 BGREWRITEAOF。
        这是它的工作原理:Redis会在最近的重写后记住AOF文件的大小(如果重启后没有重写,则使用启动时的AOF大小)。
        将此基本大小与当前大小进行比较。如果当前大小大于指定的百分比,则触发重写。此外,您需要指定要重写的AOF文件的最小大小,这有助于避免重写AOF文件,即使达到 auto-aof-rewrite-percentage 但仍然非常小。
        指定 auto-aof-rewrite-percentage = 0 以禁用自动AOF重写功能。

2.6 aof-load-truncated
        如果系统(尤其是在没有data = ordered选项的情况下挂载ext4文件系统)出现崩溃且此时 Redis 启动进程在使用 AOF 的 appendonly.aof 文件将数据加载回内存时,可能会发生 appendonly.aof 末尾出现错误(也就是末尾被截断,文件不正常终止)这种情况(但是当Redis本身崩溃或中止但操作系统仍能正常工作时,这种情况不会发生)。
        发生这种情况时,Redis可以退出,或者加载尽可能多的数据(默认值),如果发现AOF文件在末尾被截断,则启动。此选项控制此行为。
        如果将aof-load-truncated设置为yes,则会加载截断的AOF文件,并且Redis服务器会开始发出日志以通知用户该事件。
        否则,如果该选项设置为no,则服务器将中止并显示错误并拒绝启动。当该选项设置为no时,用户需要使用“redis-check-aof”实用程序修复AOF文件,然后才能重新启动服务器。
        请注意,如果发现AOF文件在中间被破坏,服务器仍将退出并显示错误。此选项仅在Redis尝试从AOF文件中读取更多数据但不会找到足够的字节时适用。

2.7 aof-use-rdb-preamble
         重写AOF文件时,Redis能够使用AOF文件中的RDB前导码来加快重写和恢复速度。启用此选项后,重写的AOF文件由两个不同的节组成:
               [RDB文件] [AOF尾]
         加载时Redis识别出AOF文件以“REDIS”字符串开头并加载前缀RDB文件,并继续加载AOF尾部。
3.AOF rewrite
    3.1 重写
        AOF 采用文件追加的方式,文件会越来越大为避免出现此种情况,新增重写机制。
        当 AOF 文件大小超过所设定的阈值时,Redis 就会启动 AOF 文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令 bgrewriteaof

3.2 重写原理
        AOF 文件持续增长而过大时,会 fork 出一条新进程来讲文件重写(先写临时文件最后在改名,默认名字为 appendonly.aof),遍历新进程的内存中数据,每条记录有一条 set 语句,重写 aof 文件,并没有读取旧的 aof 文件
        而是将整个内存中的数据用命令的方式重写了一个新的 aof 文件,这点和快照有点类似

3.3 重写触发机制
        Redis 会记录赏赐重写时的 AOF 大小,默认配置是当 AOF 文件大小是上次 rewrite 后大小的已被且文件大小大于 64M 时触发

4. AOF 同步策略
    4.1 always:每次发生写入操作时都会被立即记录到磁盘,性能较差但数据完整性比较好

4.2 everysec:异步操作,每秒记录,如果在一秒内宕机,那么将丢失 一秒的数据

4.3 no:不同步

5.AOF 劣势
    5.1 相同数据集的数据而言 aof 文件要远大于 rdb 文件,恢复速度慢于 rdb
    5.2 aof 运行效率要慢于 rdb, everysec 同步策略效率较好,no 同步策略效率和 rdb 相同

6.关于 RDB 和 AOF 这两种持久化方式的总结
    6.1 RDB
        RDB 持久化方式能够在指定的时间间隔内对你的数据进行快照存储

6.2 AOF
        AOF 持久化方式记录每次对服务器写的操作,当服务器冲i的时候会重新执行这些命令来恢复原始的数据。AOF 命令以 redis 协议追加保存每次写的操作到文件末尾
        redis 还能对 AOF 文件进行后台重写,使得 AOF 文件体积不至于过大

6.3 不开启持久化
        当然如果 redis 只做缓存的话,那么可以不用任何持久化的方式

6.4 开启持久化
        但是如果不只做缓存,那么最好同时开启两种持久化方式
        在这种情况下,redis 重启时会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据要比 RDB 文件保存的数据要完整

那么 RDB 数据不实时,而且同时使用两者时服务器重启也只会找 AOF 文件,要不要只使用 AOF 呢?(我有一个大胆的想法,你要不要听听)
        redis 开发人员建议不要,因为 RDB 更适合用于备份数据库,AOF 在不断变化不好备份
        而且快速重启后,RDB 不会有 AOF 可能潜在的bug,留着 RDB 可以作为一个以防万一的手段

6.4 开启了主从复制且开启了持久化
        因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,即只保留save 900 1这条规则。
        如果开启 AOF,好处是在最恶劣情况下也只会丢失不超过30秒数据,启动脚本较简单只加载自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF 重写的最后将重写过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF 重写的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值,例如80%。
        如果不开启 AOF ,仅靠主从复制实现高可用性也可以。能省掉一大笔IO也减少了重写时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件以便载入较新的文件。

上一篇:OpenCV成长之路(6):数学形态学基本操作及其应用


下一篇:关于开发环境中的消息在download时没有下载下来时的问题