zoukankan      html  css  js  c++  java
  • 【Redis】05 持久化

    持久化概述

    Redis提供了不同的持久性选项:

    1、RDB持久性按指定的时间间隔执行数据集的时间点快照。
    
    2、AOF持久性会记录服务器接收的每个写入操作,这些操作将在服务器启动时再次播放,以重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且仅采用追加方式。当日志太大时,Redis可以在后台重写日志。
    
    3、如果您希望,只要您的数据在服务器运行时就一直存在,则可以完全禁用持久性。
    
    4、可以在同一实例中同时合并AOF和RDB。请注意,在这种情况下,当Redis重新启动时,由于可以保证AOF文件是最完整的,因此它将用于重建原始数据集。

    要理解的最重要的事情是RDB和AOF持久性之间的不同权衡。

    让我们从RDB开始:

    RDB【Redis DataBase】

    优势

    1、RDB是Redis数据的非常紧凑的单文件时间点表示。RDB文件非常适合备份。例如,您可能希望在最近的24小时内每小时存档一次RDB文件,并在30天之内每天保存一次RDB快照。这使您可以在发生灾难时轻松还原数据集的不同版本。
    
    2、RDB对灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程数据中心或Amazon S3(可能已加密)上。
    
    3、RDB最大限度地提高了Redis的性能,因为Redis父进程为了持久化而需要做的唯一工作就是分叉一个孩子,其余所有工作都要做。父实例将永远不会执行磁盘I / O或类似操作。
    
    4、与AOF相比,RDB允许大型数据集更快地重启。

    缺点

    1、如果您需要在Redis停止工作(例如断电后)时最大程度地减少数据丢失的机会,那么RDB不好。您可以配置生成RDB的不同保存点(例如,在至少五分钟后,对数据集进行100次写操作,但是您可以有多个保存点)。但是,通常会每隔五分钟或更长时间创建一次RDB快照,因此,如果Redis出于任何原因在没有正确关闭的情况下停止工作,则应该准备丢失最新的数据分钟。
    
    2、RDB需要经常使用fork()才能使用子进程将其持久化在磁盘上。如果数据集很大,Fork()可能很耗时,并且如果数据集很大且CPU性能不佳,则可能导致Redis停止为客户端服务几毫秒甚至一秒钟。AOF还需要fork(),但您可以调整要重写日志的频率,而无需在持久性上进行权衡。

    AOF【Append Only File】

    优势

    1、使用AOF Redis更加持久:您可以有不同的fsync策略:完全没有fsync,每秒fsync,每个查询fsync。使用fsync的默认策略,每秒的写入性能仍然很好(使用后台线程执行fsync,并且在没有进行fsync的情况下,主线程将尽力执行写入操作。)但是您只能损失一秒钟的写入时间。
    
    2、AOF日志是仅追加的日志,因此,如果断电,则不会出现寻道或损坏问题。即使由于某种原因(磁盘已满或其他原因)以半写命令结束日志,redis-check-aof工具也可以轻松修复它。
    
    3、Redis太大时,Redis可以在后台自动重写AOF。重写是完全安全的,因为Redis继续追加到旧文件时,会生成一个全新的文件,其中包含创建当前数据集所需的最少操作集,一旦准备好第二个文件,Redis会切换这两个文件并开始追加到新的那一个。
    
    4、AOF以易于理解和解析的格式包含所有操作的日志。您甚至可以轻松导出AOF文件。例如,即使您使用FLUSHALL命令刷新了所有错误文件,如果在此期间未执行任何日志重写操作,您仍然可以保存数据集,只是停止服务器,删除最新命令并重新启动Redis。

    缺点

    1、对于同一数据集,AOF文件通常大于等效的RDB文件。
    
    2、根据确切的fsync策略,AOF可能比RDB慢。通常,在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用fsync的情况下,即使在高负载下,它也应与RDB一样快。即使在巨大的写负载情况下,RDB仍然能够提供有关最大延迟的更多保证。
    
    3、过去,我们在特定命令中遇到过罕见的错误(例如,其中一个涉及阻止命令,例如BRPOPLPUSH),导致生成的AOF在重载时无法重现完全相同的数据集。这些错误很少见,我们在测试套件中进行了测试,自动创建了随机的复杂数据集,然后重新加载它们以检查一切是否正常。但是,RDB持久性几乎是不可能的。为了更清楚地说明这一点:Redis AOF通过增量更新现有状态来工作,就像MySQL或MongoDB一样,而RDB快照一次又一次地创建所有内容,从概念上讲更健壮。但是-1)应当注意,每次Redis重写AOF时,都会从数据集中包含的实际数据开始从头开始重新创建AOF,与始终附加AOF文件(或重写为读取旧的AOF而不是读取内存中的数据)相比,提高了对错误的抵抗力。2)我们从未收到过有关真实环境中检测到的AOF损坏的用户报告。

    实际应用:

    通常的指示是,如果您希望获得与PostgreSQL可以提供的功能相当的数据安全性,则应同时使用两种持久性方法。

    如果您非常关心数据,但是在灾难情况下仍然可以承受几分钟的数据丢失,则可以仅使用RDB。

    有很多用户单独使用AOF,但我们不建议这样做,

    因为不时拥有RDB快照对于进行数据库备份,加快重启速度以及AOF引擎中存在错误是一个好主意。

    快照

    默认情况下,Redis将数据集的快照保存在磁盘上名为的二进制文件中

    dump.rdb

    如果数据集中至少有M个更改,可以将Redis配置为使其每N秒保存一次数据集,或者可以手动调用SAVEBGSAVE命令。

    例如,如果更改了至少1000个键,此配置将使Redis每60秒自动将数据集转储到磁盘上:


    RDB:

    save 900 1
    save 300 10
    save 60 10000

    在指定的时间间隔内将内存中的数据集快照写入磁盘,

    也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里

    Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,

    再用这个临时文件替换上次持久化好的文件。

    整个过程中,主进程是不进行任何IO操作的,

    这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,RDB方式要比AOF方式更加的高效。

    RDB的缺点是最后一次持久化后的数据可能丢失。

    Fork?

    Fork的作用是复制一个与当前进程一样的进程。

    新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程

    数据的恢复:

    将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可

    如何获取目录:

    访问Redis客户端
    ./redis-cli
    
    输入dir获取目录
    dir

    优点

    适合大规模的数据恢复

    对数据完整性和一致性要求不高

    缺点

    在一定间隔时间做一次备份,所以如果redis意外down掉的话,就 会丢失最后一次快照后的所有修改

    Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑


    AOF:

    原理

    以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),

    只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis

    重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

    保存位置 & 位置配置

    Aof保存的是appendonly.aof文件

    AOF启动/修复/恢复

    正常恢复

    启动:设置Yes  修改默认的appendonly no,改为yes将有数据的aof文件复制一份保存到对应目录(config get dir)
    恢复:重启redis然后重新加载

    异常恢复

    启动:设置Yes   修改默认的appendonly no,改为yes备份被写坏的AOF文件
    修复:Redis-check-aof --fix进行修复
    恢复:重启redis然后重新加载

    优势

    每修改同步:appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
    每秒同步:appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失
    不同步:appendfsync no 从不同步

    劣势

    相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
    Aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

    实际应用:

    整理我们的理解及处理方式

    1、RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
    
    2、AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些 命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾. Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

    只做缓存

    如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

    同时开启两种持久化方式

    1、在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
    
    2、RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。

    性能建议

    1、因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
    
    2、如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
    
    3、如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构
  • 相关阅读:
    统计创建对象个数
    动手动脑
    开学第一周心得
    放假第五周总结
    放假第四周总结
    第一周总结
    04-异常处理-动手动脑
    03-继承与多态-动手动脑
    02-类和对象-跟踪类对象创建个数
    02-类和对象-动手动脑
  • 原文地址:https://www.cnblogs.com/mindzone/p/13458651.html
Copyright © 2011-2022 走看看