zoukankan      html  css  js  c++  java
  • Redis-持久化机制

    1 持久化机制

      Redis 速度快,很大一部分原因是因为它所有的数据都存储在内存中。如果断电或者宕机,都会导致内存中的数据丢失。为了实现重启后数据不丢失,Redis 提供了两种持久

    化的方案,一种是 RDB 快照(Redis DataBase),一种是 AOF(Append Only File)。

    1.1 RDB

      RDB 是 Redis 默认的持久化方案。当满足一定条件的时候,会把当前内存中的数据写入磁盘,生成一个快照文件 dump.rdb。Redis 重启会通过加载 dump.rdb 文件恢

    复数据。

      什么时候写入 rdb 文件?

    1.1.1 RDB 触发

    1、自动触发

      a)配置规则触发。
      redis.conf, SNAPSHOTTING,其中定义了触发把数据保存到磁盘的触发频率。如果不需要 RDB 方案,注释 save 或者配置成空字符串""。
    save 900 1 # 900 秒内至少有一个 key 被修改(包括添加) 
    save 300 10 # 400 秒内至少有 10 个 key 被修改
    save 60 10000 # 60 秒内至少有 10000 个 key 被修改

      注意上面的配置是不冲突的,只要满足任意一个都会触发。

      RDB 文件位置和目录:
    # 文件路径, 
    dir ./
    # 文件名称
    dbfilename dump.rdb
    # 是否是 LZF 压缩 rdb 文件
    rdbcompression yes
    # 开启数据校验
    rdbchecksum yes
    RDB 还有两种触发方式:
    b)shutdown 触发,保证服务器正常关闭。
    c)flushall,RDB 文件是空的,没什么意义(删掉 dump.rdb 演示一下)。

    2、手动触发

      如果我们需要重启服务或者迁移数据,这个时候就需要手动触 RDB 快照保存。Redis提供了两条命令:

    a)save

      save 在生成快照的时候会阻塞当前 Redis 服务器, Redis 不能处理其他命令。如果内存中的数据比较多,会造成 Redis 长时间的阻塞。生产环境不建议使用这个命令。

      为了解决这个问题,Redis 提供了第二种方式。

    b)bgsave

      执行 bgsave 时,Redis 会在后台异步进行快照操作,快照同时还可以响应客户端请求。

      具体操作是 Redis 进程执行 fork 操作创建子进程(copy-on-write),RDB 持久化过程由子进程负责,完成后自动结束。它不会记录 fork 之后后续的命令。阻塞只发生在

    fork 阶段,一般时间很短。

      用 lastsave 命令可以查看最近一次成功生成快照的时间。

    RDB 文件的优势和劣势

    一、优势

    1.RDB 是一个非常紧凑(compact)的文件,它保存了 redis 在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复。

    2.生成 RDB 文件的时候,redis 主进程会 fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘 IO 操作。

    3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

    二、劣势

    1、RDB 方式数据没办法做到实时持久化/秒级持久化。因为 bgsave 每次运行都要执行 fork 操作创建子进程,频繁执行成本过高。

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

      如果数据相对来说比较重要,希望将损失降到最小,则可以使用 AOF 方式进行持久化。

    1.2 AOF

      Append Only File
      AOF:Redis 默认不开启。AOF 采用日志的形式来记录每个写操作,并追加到文件中。开启后,执行更改 Redis 数据的命令时,就会把命令写入到 AOF 文件中。
      Redis 重启时会根据日志文件的内容把写指令从前到后执行一次以完成数据的恢复工作。

    1.2.1 AOF 配置

      配置文件 redis.conf
    # 开关 
    appendonly no
    # 文件名
    appendfilename "appendonly.aof"

    appendonly :

      Redis 默认只开启 RDB 持久化,开启 AOF 需要修改为 yes

    appendfilename "appendonly.aof" :

      路径也是通过 dir 参数配置 config get dir

    问题:数据都是实时持久化到磁盘吗?

      由于操作系统的缓存机制,AOF 数据并没有真正地写入硬盘,而是进入了系统的硬盘缓存。什么时候把缓冲区的内容写入到 AOF 文件?

    appendfsync everysec :

      AOF 持久化策略(硬盘缓存到磁盘),默认 everysec

    •  no 表示不执行 fsync,由操作系统保证数据同步到磁盘,速度最快,但是不太安全;

    •  always 表示每次写入都执行 fsync,以保证数据同步到磁盘,效率很低;

    •  everysec 表示每秒执行一次 fsync,可能会导致丢失这 1s 数据。通常选择 everysec ,兼顾安全性和效率。

    问题:文件越来越大,怎么办?

      由于 AOF 持久化是 Redis 不断将写命令记录到 AOF 文件中,随着 Redis 不断的进行,AOF 的文件会越来越大,文件越大,占用服务器内存越大以及 AOF 恢复要求时间

    越长。

      例如 set gupao 666,执行 1000 次,结果都是 gupao=666。

      为了解决这个问题,Redis 新增了重写机制,当 AOF 文件的大小超过所设定的阈值时,Redis 就会启动 AOF 文件的内容压缩,只保留可以恢复数据的最小指令集。

      可以使用命令 bgrewriteaof 来重写。

      AOF 文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原

    来的 AOF 文件。

    # 重写触发机制 
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb

    auto-aof-rewrite-percentage :

      默认值为 100。aof 自动重写配置,当目前 aof 文件大小超过上一次重写的 aof 文件大小的百分之多少进行重写,即当 aof 文件增长到一定大小的时候,Redis 能够调用 bgrewriteaof
    对日志文件进行重写。当前 AOF 文件大小是上次日志重写得到 AOF 文件大小的二倍(设置为 100)时,自动启动新的日志重写过程。

    auto-aof-rewrite-min-size :

      默认 64M。设置允许重写的最小 aof 文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。

    问题:重写过程中,AOF 文件被更改了怎么办?

    另外有两个与 AOF 相关的参数:

    no-appendfsync-on-rewrite :

      在 aof 重写或者写入 rdb 文件的时候,会执行大量 IO,此时对于 everysec 和 always 的 aof模式来说,执行 fsync 会造成阻塞过长时间,no-appendfsync-on-rewrite 字段设置为默认设

    置为 no。如果对延迟要求很高的应用,这个字段可以设置为 yes,否则还是设置为 no,这样对持久化特性来说这是更安全的选择。设置为 yes 表示 rewrite 期间对新写操作不 fsync,

    暂时存在内存中,等 rewrite 完成后再写入,默认为 no,建议修改为 yes。Linux 的默认 fsync策略是 30 秒。可能丢失 30 秒数据。

    aof-load-truncated :

      aof 文件可能在尾部是不完整的,当 redis 启动的时候,aof 文件的数据被载入内存。重启可能发生在 redis 所在的主机操作系统宕机后,尤其在 ext4 文件系统没有加上 data=ordered

    选项,出现这种现象。redis 宕机或者异常终止不会造成尾部不完整现象,可以选择让 redis退出,或者导入尽可能多的数据。如果选择的是 yes,当截断的 aof 文件被导入的时候,

    会自动发布一个 log 给客户端然后 load。如果是 no,用户必须手动 redis-check-aof 修复 AOF文件才可以。默认值为 yes。

      重启 Redis 之后就会进行 AOF 文件的恢复。

     

    AOF 优势与劣势

    优点:

    1、AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。

    缺点:

    1、对于具有相同数据的的 Redis,AOF 文件通常会比 RDF 文件体积更大(RDB存的是数据快照)。

    2、虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。在高并发的情况下,RDB 比 AOF 具好更好的性能保证。

    两种方案比较

      那么对于 AOF 和 RDB 两种持久化方式,我们应该如何选择呢?

      如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要

    比 AOF 恢复的速度要快。

      否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始

    的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。

  • 相关阅读:
    (4.3)ODBC/OLE DB/ADO概念与使用情况
    查找至少连续出现三次的所有数字/连续3天的日期【LeetCode】
    javascript 事件触发
    document.referrer
    创业公司
    关于javascript 回调函数
    promise
    javascript deferred
    document.readystate
    window---->load, document------DOMContentLoaded
  • 原文地址:https://www.cnblogs.com/talkingcat/p/13815818.html
Copyright © 2011-2022 走看看