当前位置: 首页 > news >正文

Redis持久化机制(RDB AOF)

1. RDB

        RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发和 自动触发,存储的是二进制数据。

1.1 手动触发

使用 save 和 bgsave 命令触发:

  • save:Redis服务主进程阻塞式执行持久化操作,直到RDB过程结束,在此期间 Redis 服务端无法执行客户端的命令,持久化数据量大的情况下,会导致主进程长时间阻塞,使用较少;
  • bgsave:后台执行持久化操作,Redis主进程使用 fork 创建子进程,RDB持久化过程由子进程负责执行,阻塞时间较短,只发生在fork阶段;

1.2 自动触发

  • 自动触发在 Redis 配置文件 redis.conf 中进行配置, 比如:如 "save m n" 表示 m 秒内数据集发生了 n 次修改,自动 RDB 持久化。
  • 从节点进行全量复制操作时,主节点⾃动进行 RDB 持久化,随后将 RDB ⽂件内容发送给从结点。
  • 执行 shutdown 命令关闭 Redis 时,也会执行RDB 持久化。

1.3 持久化流程

    RDB 是快照式的数据保存,常见的持久化操作都是在 后台进行的(bgsave)流程如下:

    1.  检查是否已有持久化进程运行​,如果有就直接返回;
    2. Redis 主进程调用 fork()创建子进程,fork 过程会短暂阻塞主线程(阻塞时间取决于内存大小和系统性能),且由于 父进程创建的子进程和父进程共享数据,详细介绍可见【Linux进程】进程地址空间-CSDN博客
    3. 父进程 fork 完成后,bgsave 命令返回 "Background saving started" 信息并不再阻塞父进程,可以继续响应其他命令。
    4. 子进程创建 RDB ⽂件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。
    5. 进程发送信号给父进程示完成,父进程更新统计信息

    1.4 RDB文件

    RDB 文件默认在 /var/lib/redis/ 下,文件名通过 dbfilename 配置(默认为 dump.rdb)指定;config set dir {newDir} 和 config set dbfilename  {newFilename} 运行期间动态执行,当下次运行时 RDB 文件会保存到新目录

    Redis 默认采⽤ LZF 算法对生成的 RDB ⽂件做压缩处理,压缩后的⽂件远远小于内存大小,默认开启,可以通过参数 config set rdbcompression {yes|no} 动态修改。

    注意:如果 Redis 启动时加载到损坏的 RDB 文件会拒绝启动。这时可以使用 Redis 提供的 redischeck-dump ⼯具检测 RDB 文件并获取对应的错误报告。

    1.5 优缺点

    优点

    • RDB 是⼀个紧凑压缩的⼆进制⽂件,存储 Redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景;
    • 数据恢复速度比 AOF 快;

    缺点:

    • 无法实时持久化(每次都会fork创建子进程,该操作属于重量级操作,频繁创建会严重影响性能);
    • RDB 文件使用特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有风险。

    2. AOF

    AOF(Append Only File)持久化:以独立日志的方式记录每次的写命令,重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。AOF 的主要作用是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式。

    写入的数据可读性也相对较好,比如:set hello world

    那么在文件中就会追加以下文本:

    *3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

    2.1 配置 AOF

    开启 AOF 功能需要设置配置:appendonly yes,默认不开启。AOF 文件名通过 appendfilename 配置(默认是 appendonly.aof)设置。保存目录同 RDB 持久化方式⼀致,通过 dir 配置指定;

    2.2 工作流程

    1. 所有的写入命令会追加到 aof_buf(缓冲区)中。

    2. AOF 缓冲区根据对应的策略向硬盘做同步操作。 

    3. 随着 AOF文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。

    4. 当 Redis 服务器启动时,可以加载 AOF 文件进行数据恢复。

    2.3 文件同步

    由于存在缓冲区的缘故,对于缓冲区同步到文件主要分为三种策略:

    可配置值

    说明

    数据安全性

    性能影响

    适用场景

    ​always​

    每次写入命令后立即调用 fsync同步到磁盘,完成后才返回成功响应。

    最高

    性能最低(频繁磁盘 I/O)

    对数据一致性要求极高的场景(如金融交易)

    ​everysec​

    命令先写入内存缓冲区(aof_buf),随后调用 write操作(不立即 fsync)。后台线程每秒执行一次 fsync

    中等

    性能与安全的平衡(推荐默认值)

    大多数生产环境

    ​no​

    命令写入 aof_buf后仅调用 write操作,由操作系统决定何时 fsync(通常间隔 30 秒或缓冲区满)。

    最低

    性能最高(但可能丢失更多数据)

    可容忍少量数据丢失的高吞吐场景

    write 和 fsync说明:

    write:write会触发操作系统的延迟写机制,write 操作在写入系统缓冲区后就会立即返回;同步到硬盘操作依赖于系统调度机制;如果数据在操作系统缓冲区内还没落盘,此时发生断电或系统宕机,那么缓冲区数据就会丢失;

    fsync:针对单个文件操作,做强制硬盘同步,fsync 将阻塞直到数据写入到硬盘;

    2.4 重写机制

    随着命令不断写入 AOF,文件会越来越大,为了解决这个问题,Redis 引⼊ AOF 重写机制压缩⽂ 件体积。

    为什么会越来越大?比如:

    set k1 v1
    set k2 v2
    del k1

    数据实际只存储了 k2 - v2,但存储了三条命令;重写机制可以认为是对 AOF 文件的整理;比如:

    • 进程内已超时的数据不再写入文件。
    • 旧的 AOF 中的无效命令,例如 del、hdel、srem 等重写后将会删除,只需要保留数据的最终版 本。
    • 多条写操作合并为⼀条,例如 lpush list a、lpush list b、lpush list c 可以合并为 lpush list a b c。

    AOF 重写过程可以手动动触发和自动触发:

    • 手动触发:调用 bgrewriteaof 命令。 
    • 自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时机

    auto-aof-rewrite-min-size:表示触发重写时 AOF 的阈值,默认为 64MB。

    auto-aof-rewrite-percentage:代表当前 AOF 占用大小相比较上次重写时增加的比例。

    2.5 重写流程

    1. 执行重写请求,如果当前进程正在执行 AOF 重写,请求不执行。如果当前进程正在执行 bgsave 操作,重写命令延迟到 bgsave 完成之后再执行。

    2. 父进程执行 fork 创建子进程

    3. 重写

            3.1 主进程 fork 之后继续响应其他命令,后续所有修改操作会被记录到 aof_buf 中,根据策略进行落盘;

            3.2 子进程只有fork之前的所有内存数据,在子进程重写的期间,父进程需要将修改操作写入 AOF 重写缓冲区中;

    4. 子进程根据内存快照,读取内存中数据,整理后写入到新的AOF文件中;

    5. 完成重写,进行AOF文件替换

            5.1 新文件写入后,子进程发送信号给父进程。

            5.2 父进程把 AOF 重写缓冲区内临时保存的命令追加到新 AOF ⽂件中。

            5.3 用新 AOF 文件替换旧 AOF 文件。

    3. 启动时数据恢复

    当 Redis 启动时,会根据 RDB 和 AOF 文件的内容,进行数据恢复;

    ​当 Redis 重启时,如果 AOF 文件和 RDB 文件同时存在,Redis 会优先使用 AOF 文件进行数据恢复​;

    ​步骤​

    ​行为​

    ​检查 AOF 是否启用​

    如果 appendonly yes(AOF 已启用),则​​跳过 RDB​​,直接加载 AOF 文件。

    ​AOF 文件不存在/损坏​

    如果 AOF 文件不可用(如文件损坏),则尝试加载 RDB 文件作为备用恢复。

    ​AOF 和 RDB 均未启用​

    启动一个空数据集(无持久化数据)。

    http://www.dtcms.com/a/329988.html

    相关文章:

  • Form.Item中判断其他Form.Item的值
  • 边学边做边玩:我的类魂斗罗Java小游戏与Java学习(1)
  • 《MySQL 实战:从建库建表到复杂查询的完整操作指南》
  • Android Framework定制长按电源键关机的窗口
  • 9 ABP Framework 中的 MVC 和 Razor Pages
  • Java pdf工具
  • jvm学习笔记之jvm的生命周期和发展历程
  • Video_AVI_Packet(2)
  • 全球AI安全防护迈入新阶段:F5推出全新AI驱动型应用AI安全解决方案
  • 量子安全新纪元:F5发布全新AI驱动的全栈式后量子加密AI安全方案
  • OpenJDK 17 源码 安全点轮询的信号处理流程
  • ESP-IDF 编译系统说明
  • 单细胞测序分析平台在肿瘤免疫微环境研究中的应用
  • javascript学习
  • element-ui 树形结构的table,自定义展开收起小箭头所在的列
  • 若依前后端分离版学习笔记(九)——登录和操作日志
  • Pyside6 核心模块随笔
  • VS2022+QT5.15.2+OCCT7.9.1的开发环境搭建流程
  • Pytest+selenium UI自动化测试实战实例(超详细)
  • 【css】让浏览器支持小于12px的文字
  • 各种排序算法(二)
  • OpenBMC中的BMCWeb:架构、原理与应用全解析
  • 焊接工业机器人节气装置
  • Apple 的 GPU 加速框架
  • JavaWeb(05)
  • 汽车免拆诊断案例 | 2017 款丰田皇冠车行驶中加速时车身偶尔抖动
  • 【ARM】keil提示UVISION: Error: Encountered an improper argument
  • PCBA:电子产品制造的核心环节
  • Video_AVI_Packet(1)
  • Linux服务器启动应用缓慢的解决方案