美文网首页
Redis两种持久化方式对比

Redis两种持久化方式对比

作者: 非典型_程序员 | 来源:发表于2019-03-10 19:56 被阅读0次

    Redis数据持久化以及两种方式的优缺点也是面试中经常遇到的问题,今天就来学习一下RDB和AOF两种持久化方案的配置以及它们的优缺点。

    一、RDB

    RDB是将某个时间点的快照存储到硬盘上,Redis配置文件设置方式如下:

    save <seconds> <changes>
    

    也就是说当既满足一定时间值(秒)和一定数量写操作的情况下,Redis会将DB存储到硬盘,可以设置多个时间节点,比如:

    save 900 1  # 15分钟内有一个写操作
    save 300 10 # 5分钟内有10个写操作
    save 60 10000 # 1分钟内有10000个写操作
    

    只要达到了设置的节点值,就会触发Redis将数据存储到硬盘。默认情况下,如果启用RDB快照并且最近一次的后台保存失败,那么Redis将停止接受写入数据。这样用户会意识到数据没能正确保存在硬盘上,否则的话没有人会注意到将要发生一些事故。


    stop-writes-on-bgsave-error yes
    

    上面这个配置,是否在后台保存出错的情况下停止写入,默认是yes。但是如果已经对Redis服务器和持久化的进行了合理的监控配置,那么最好禁用此功能,以便即使因为硬盘、权限等问题,Redis也将继续正常工作。


    是否在转存使用LZF压缩字符串对象,默认设置是yes,
    如果想节约CPU资源的话,可以将其设置为no,但这样可能会导致数据集比较大。

    rdbcompression yes  # 是否开启压缩功能
    

    从RDB的5版本开始,一个CRC64(循环冗余校验)的校验和会被放置在文件的末尾。这么做的优势是文件更能抵抗损坏风险,缺点是在保存或者加载RDB文件时需要付出额外的性能(大约10%),可以禁用它以便将性能最大化,这个看个人选择了。

    rdbchecksum yes  # 是否开启校验和
    

    除了这些以外还有两个配置,分别是指定持久化到本地硬盘的文件名称以及文件存储的位置

    dbfilename dump.rdb  # 数据集文件名称
    dir ./   # 这里必须指定的是文件夹
    

    二、AOF

    AOF,即Append Only File,就是仅仅追加数据的意思。这种方式在默认情况下,Redis会以异步方式将数据转储到硬盘上。 这种方式在许多应用中表现都足够好,但是Redis进程或停电等问题可能导致几分钟的写入丢失。
    使用默认的fsync策略,在服务器断电等极端情况下中只会丢失一秒写入,如果是Redis进程本身出的现问题,则会丢失一次写入,但是操作系统仍然正常运行。
    RDB和AOF是可以同时使用的,如果启动时启用AOF,那么Redis将会去加载AOF,这样能保证更好的持久性。 是否启用AOF以及保存的文件名称配置如下:

    appendonly no  # 是否启动AOF
    appendfilename "appendonly.aof"  # 默认是"appendonly.aof"
    

    fsync()函数调用告诉操作系统将数据实时写入硬盘,而不是等待输出缓冲区中的更多数据。一些操作系统会真正刷新将数据刷新到硬盘,其他一些操作系统只会尽快完成。fsync()是unix系统的系统级别函数,有兴趣的可以找资料了解一下。Redis支持三种不同的策略:

    1、no,不调用fsync,即由操作系统自己决定何时刷新数据,这种速度很快。
    2、always,每次写入追加日志后调用fsync,速度慢,但是最安全。
    3、everysec,每一秒调用fsync,折中方案。

    默认是everysec,这是一个折中考虑。你也可以决定是否选择为no,由操作系统决定何时刷新输出缓冲区,以便达到更好的性能。或者选择always,虽然速度变慢,但是却有更好的安全性。不确定自己应该选择哪种的话,就选择默认就好,即everysec。

    # appendfsync no
    # appendfsync always
    appendfsync everysec  # 默认
    

    当fsync策略设置为always或everysec,且后台保存进程(后台保存或AOF日志后台重写)正在对硬盘执行大量I/O操作时,在某些Linux配置中,Redis可能会在fsync()调用时阻塞太长时间。 目前没有对这个问题进行修复,因为即使在不同的线程中执行fsync也会阻塞我们同步write(2)函数调用。
    为了缓解这个问题,可以使用下面的这个配置,以防止在BGSAVE或BGREWRITEAOF正在进行时,在主进程中调用fsync()函数。 这意味着当另一个子进程正在进行保存时,Redis的持久性与“appendfsync none”相同。 实际上,这意味着在最糟糕的情况下(使用默认的Linux设置)可能会丢失最多30秒的日志。 如果对延迟觉得有问题,可以将其改为yes。 否则,从持久性观点看得话,设置为no应该是最安全的。

    no-appendfsync-on-rewrite no
    

    当AOF日志大小增长到指定的百分比时,Redis能够通过隐性调用BGREWRITEAOF自动重写日志文件。它的工作原理是这样的:Redis在最近重写后可以记住AOF文件的大小(如果重启后没有重写,使用启动时AOF的大小)。将此基础上大小与当前文件大小进行比较,如果当前文件大于指定的百分比,则触发重写。 并且还需要指定要重写的AOF文件的最小大小,这助于避免重写AOF文件,即使已经达到指定百分比,但是文件仍然非常小。如果要禁用AOF自动重写功能可以将百分比设置为0。


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

    aof-load-truncated yes
    

    当重写AOF文件时,Redis能够在AOF文件使用RDB前导码以便更快的重写和恢复。当这个选项开启时候,重写的AOF文件由两个不同的字节组成:

    [RDB file][AOF tail]

    当加载时Redis识别出AOF文件以“REDIS”字符串开头,并加载前缀的RDB文件,然后继续加载AOF文件尾部。为了避免格式更改的意外,这个配置默认是关闭的。

    aof-use-rdb-preamble no  # 默认为no
    

    三、RDB和AOF优缺点

    一、RDB优点

    1、RDB是一个非常紧凑的时间点(point-in-time)单文件,这个文件代表着Redis的数据。RDB文件非常适合用来备份。比如,你可能希望在最近24小时内每小时归档一份RDB文件,并且30天内每天保存一份RDB快照。这样可以在发生问题时轻松恢复不同版本的数据集。
    2、RDB非常适合灾难恢复,因为它是一个单独的压缩文件,可以将它传递到远程数据中心。
    3、RDB可以最大化Redis的性能:父进程在保存 RDB 文件时唯一要做的就是fork出一个子进程,然后由这个子进程处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O操作。
    4、与AOF相比,RDB恢复大量数据集时重启速度更快。

    二、RDB缺点

    1、如果你需要在Redis停止工作的情况下最大限度地减少数据丢失,RDB相对并不好。虽然Redis可以设置多个保存点,Redis需要保存每个节点数据集,这并不是一个轻松的操作。一旦发生故障导致Redis停机,你就可能会丢失最近几分钟的数据。
    2、RDB经常需要fork()从而使用子进程将数据存储在硬盘上。如果数据集很大fork()是非常消耗时间的。如果数据集很大,而CPU性能又不是太好的话,可能会导致Redis服务端在某个较短的时间段内(几毫秒,甚至一秒钟)无法响应客户端请求。

    三、AOF优点

    1、使用AOF能够使Redis的持久性更好,你可以设置不同的fsync策略,比如:设置为no,或者每秒钟,抑或每次写入。在使用默认策略(即每秒钟)的情况下,Redis的写入性能依然非常好,而你最多也只会丢失一秒钟的数据。fsync通过使用后台线程执行,当没有fsync正在进行时,主线程将尽力执行写入操作。
    2、AOF 是一个只进行追加操作的日志文件,对 AOF 文件写入时不需要进行搜寻、或者因为停电的损坏问题。即使日志文件因为某些原因(比如硬盘已满或者其他原因)而包含了未写入完整的命令,redis-check-aof 工具也可以轻易地修复这些问题。
    3、当Redis获取的数据过大时,Redis能够在后台自动重写AOF文件。重写是完全安全的,因为Redis会继续在旧文件进行追加。Redis使用创建当前数据集所需的最小操作集生成一个全新的操作,一旦第二个文件准备就绪,Redis会切换两个并开始附加到新数据集。
    4、AOF以一种能够简单理解和解析的格式包含了所有Redis有序的操作日志。你甚至可以轻松导出AOF文件。比如,即使你使用FLUSHALL命令刷新了所有错误,如果在此期间还未执行过重写日志,你仍然可以保存数据集,只需要停止Redis服务器,删除最新命令,然后重新启动Redis。

    四、AOF缺点

    1、对于相同的数据集来说,使用AOF会比使用RDB文件大。
    2、根据的fsync策略不同,AOF速度可能比RDB慢。一般情况下fsync设置为每秒性能仍然非常高,并且在fsync禁用的情况下即使在高负载下也应该与RDB一样快。在写入负载很大的情况下,RDB仍能够提供有关最大延迟的更多保证。
    3、在过去AOF遇到了特定命令中的罕见bug,导致生成的AOF在重新加载时不能完全恢复到与原来相同的数据集。这种情况非常少见,但是确实出现过。

    相关文章

      网友评论

          本文标题:Redis两种持久化方式对比

          本文链接:https://www.haomeiwen.com/subject/dwbhuqtx.html