300分钟吃透分布式缓存-24讲:Redis崩溃后,如何进行数据恢复的?

在这里插入图片描述
Redis 持久化是一个将内存数据转储到磁盘的过程。Redis 目前支持 RDB、AOF,以及混合存储三种模式。

RDB
Redis 的 RDB 持久化是以快照的方式将内存数据存储到磁盘。在需要进行 RDB 持久化时,Redis 会将内存中的所有数据以二进制的格式落地,每条数据存储的内容包括过期时间、数据类型、key,以及 value。当 Redis 重启时,如果 appendonly 关闭,则会读取 RDB 持久化生成的二进制文件进行数据恢复。

触发构建 RDB 的场景主要有以下四种。

  1. 第一种场景是通过 save 或 bgsave 命令进行主动 RDB 快照构建。它是由调用方调用 save 或 bgsave 指令进行触发的。

  2. 第二种场景是利用配置 save m n 来进行自动快照生成。它是指在 m 秒中,如果插入或变更 n 个 key,则自动触发 bgsave。这个配置可以设置多个配置行,以便组合使用。由于峰值期间,Redis 的压力大,变更的 key 也比较多,如果再进行构建 RDB 的操作,会进一步增加机器负担,对调用方请求会有一定的影响,所以线上使用时需要谨慎。

  3. 第三种场景是主从复制,如果从库需要进行全量复制,此时主库也会进行 bgsave 生成一个 RDB 快照。

  4. 第四种场景是在运维执行 flushall 清空所有数据,或执行 shutdown 关闭服务时,也会触发 Redis 自动构建 RDB 快照。
    在这里插入图片描述
    save 是在主进程中进行 RDB 持久化的,持久化期间 Redis 处于阻塞状态,不处理任何客户请求,所以一般使用较少。而 bgsave 是 fork 一个子进程,然后在子进程中构建 RDB 快照,构建快照的过程不直接影响用户的访问,但仍然会增加机器负载。线上 Redis 快照备份,一般会选择凌晨低峰时段,通过 bgsave 主动触发进行备份。

RDB 快照文件主要由 3 部分组成。

  1. 第一部分是 RDB 头部,主要包括 RDB 的版本,以及 Redis 版本、创建日期、占用内存等辅助信息。

  2. 第二部分是各个 RedisDB 的数据。存储每个 RedisDB 时,会首先记录当前 RedisDB 的DBID,然后记录主 dict 和 expire dict 的记录数量,最后再轮询存储每条数据记录。存储数据记录时,如果数据有过期时间,首先记录过期时间。如果 Redis 的 maxmemory_policy 过期策略采用 LRU 或者 LFU,还会将 key 对应的 LRU、LFU 值进行落地,最后记录数据的类型、key,以及 value。

  3. 第三部部分是 RDB 的尾部。RDB 尾部,首先存储 Redis 中的 Lua 脚本等辅助信息。然后存储 EOF 标记,即值为 255 的字符。最后存 RDB 的 cksum。

至此,RDB 就落地完毕。

RDB 采用二进制方式存储内存数据,文件小,且启动时恢复速度快。但构建 RDB 时,一个快照文件只能存储,构建时刻的内存数据,无法记录之后的数据变更。构建 RDB 的过程,即便在子进程中进行,但仍然属于 CPU 密集型的操作,而且每次落地全量数据,耗时也比较长,不能随时进行,特别是不能在高峰期进行。由于 RDB 采用二进制存储,可读性差,而且由于格式固定,不同版本之间可能存在兼容性问题。

AOF
在这里插入图片描述
Redis 的 AOF 持久化是以命令追加的方式进行数据落地的。通过打开 appendonly 配置,Redis 将每一个写指令追加到磁盘 AOF 文件,从而及时记录内存数据的最新状态。这样即便 Redis 被 crash 或异常关闭后,再次启动,也可以通过加载 AOF,来恢复最新的全量数据,基本不会丢失数据。

AOF 文件中存储的协议是写指令的 multibulk 格式,这是 Redis 的标准协议格式,所以不同的 Redis 版本均可解析并处理,兼容性很好。

但是,由于 Redis 会记录所有写指令操作到 AOF,大量的中间状态数据,甚至被删除的过期数据,都会存在 AOF 中,冗余度很大,而且每条指令还需通过加载和执行来进行数据恢复,耗时会比较大。

AOF 数据的落地流程如下。Redis 在处理完写指令后,首先将写指令写入 AOF 缓冲,然后通过 server_cron 定期将 AOF 缓冲写入文件缓冲。最后按照配置策略进行 fsync,将文件缓冲的数据真正同步写入磁盘。
在这里插入图片描述
Redis 通过 appendfsync 来设置三种不同的同步文件缓冲策略。

  1. 第一种配置策略是 no,即 Redis 不主动使用 fsync 进行文件数据同步落地,而是由操作系统的 write 函数去确认同步时间,在 Linux 系统中大概每 30 秒会进行一次同步,如果 Redis 发生 crash,就会造成大量的数据丢失。

  2. 第二种配置策略是 always,即每次将 AOF 缓冲写入文件,都会调用 fsync 强制将内核数据写入文件,安全性最高,但性能上会比较低效,而且由于频繁的 IO 读写,磁盘的寿命会大大降低。

  3. 第三种配置策略是 everysec。即每秒通过 BIO 线程进行一次 fsync。这种策略在安全性、性能,以及磁盘寿命之间做较好的权衡,可以较好的满足线上业务需要。
    在这里插入图片描述
    随着时间的推移,AOF 持续记录所有的写指令,AOF 会越来越大,而且会充斥大量的中间数据、过期数据,为了减少无效数据,提升恢复时间,可以定期对 AOF 进行 rewrite 操作。

AOF 的 rewrite 操作可以通过运维执行 bgrewiretaof 命令来进行,也可以通过配置重写策略进行,由 Redis 自动触发进行。当对 AOF 进行 rewrite 时,首先会 fork 一个子进程。子进程轮询所有 RedisDB 快照,将所有内存数据转为 cmd,并写入临时文件。在子进程 rewriteaof 时,主进程可以继续执行用户请求,执行完毕后将写指令写入旧的 AOF 文件和 rewrite 缓冲。子进程将 RedisDB 中数据落地完毕后,通知主进程。主进程从而将 AOF rewite 缓冲数据写入 AOF 临时文件,然后用新的 AOF 文件替换旧的 AOF 文件,最后通过 BIO 线程异步关闭旧的 AOF 文件。至此,AOF 的 rewrite 过程就全部完成了。
在这里插入图片描述
AOF 重写的过程,是一个轮询全部 RedisDB 快照,逐一落地的过程。每个 DB,首先通过 select $db 来记录待落的 DBID。然后通过命令记录每个 key/value。对于数据类型为 SDS 的value,可以直接落地。但如果 value 是聚合类型,则会将所有元素设为批量添加指令,进行落地。

对于 list 列表类型,通过 RPUSH 指令落地所有列表元素。对于 set 集合,会用 SADD 落地所有集合元素。对于 Zset 有序集合,会用 Zadd 落地所有元素,而对于 Hash 会用 Hmset 落地所有哈希元素。如果数据带过期时间,还会通过 pexpireat 来记录数据的过期时间。

AOF 持久化的优势是可以记录全部的最新内存数据,最多也就是 1-2 秒的数据丢失。同时 AOF 通过 Redis 协议来追加记录数据,兼容性高,而且可以持续轻量级的保存最新数据。最后因为是直接通过 Redis 协议存储,可读性也比较好。

AOF 持久化的不足是随着时间的增加,冗余数据增多,文件会持续变大,而且数据恢复需要读取所有命令并执行,恢复速度相对较慢。

混合持久化
在这里插入图片描述
Redis 在 4.0 版本之后,引入了混合持久化方式,而且在 5.0 版本后默认开启。前面讲到 RDB 加载速度快,但构建慢,缺少最新数据。AOF 持续追加最新写记录,可以包含所有数据,但冗余大,加载速度慢。混合模式一体化使用 RDB 和 AOF,综合 RDB 和 AOF 的好处。即可包含全量数据,加载速度也比较快。可以使用 aof-use-rdb-preamble 配置来明确打开混合持久化模式。

混合持久化也是通过 bgrewriteaof 来实现的。当启用混合存储后,进行 bgrewriteaof 时,主进程首先依然是 fork 一个子进程,子进程首先将内存数据以 RDB 的二进制格式写入 AOF 临时文件中。然后,再将落地期间缓冲的新增写指令,以命令的方式追加到临时文件。然后再通知主进程落地完毕。主进程将临时文件修改为 AOF 文件,并关闭旧的 AOF 文件。这样主体数据以 RDB 格式存储,新增指令以命令方式追加的混合存储方式进行持久化。后续执行的任务,以正常的命令方式追加到新的 AOF 文件即可。

混合持久化综合了 RDB 和 AOF 的优缺点,优势是包含全量数据,加载速度快。不足是头部的 RDB 格式兼容性和可读性较差。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272388.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

StarUML6.0.1使用

1. 简介 作为一个软件开发人员,平时免不了做一定的软件设计,标准做法就是采用UML来设计: 讨论功能流程时采用时序图、活动图来表达;做业务功能架构时采用组件图来表达;做系统部署架构时采用部署图来表达;做…

linux 日志轮转

前言: 在Linux系统中,日志轮转是一种重要的管理机制,它可以帮助管理日志文件的大小、数量以及保持系统的性能稳定。通过日志轮转,可以定期对日志文件进行归档、压缩或清理,确保系统的日志记录不会无限增长而占用过多的磁盘空间…

JWT身份验证

在实际项目中一般会使用jwt鉴权方式。 JWT知识点 jwt,全称json web token ,JSON Web令牌是一种开放的行业标准RFC 7519方法,用于在两方安全地表示声明。具体网上有许多文章介绍,这里做简单的使用。 1.数据结构 JSON Web Token…

数字人ai直播软件突破AI大模型技术,改变未来科技格局!

数字人AI直播软件在AI大模型技术上的突破,将不可避免地改变未来科技格局。这一突破让人们看到了AI技术的无限可能性,并为未来的科技发展打开了新的大门。 AI大模型技术是近年来人工智能领域的一个热点,它通过构建庞大、复杂的神经网络模型&a…

【AI视野·今日NLP 自然语言处理论文速览 第八十三期】Wed, 6 Mar 2024

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 6 Mar 2024 Totally 74 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers MAGID: An Automated Pipeline for Generating Synthetic Multi-modal Datasets Authors Hossein Aboutalebi, …

Vue:自动按需导入element-plus图标

自动导入使用 unplugin-icons 和 unplugin-auto-import 从 iconify 中自动导入任何图标集。 完整vite.config.js参考模板 https://download.csdn.net/download/ruancexiaoming/88928539 导入element-plus图标 命令行安装unplugin-icons pnpm i -D unplugin-icons//没有安装自…

手写简易操作系统(二)--启动计算机

前情提要 在上一部分的内容中,我们已经做好了模拟仿真的整个准备工作,这一节我们就先把计算机启动起来。 一、Bochs配置 1.1、配置启动盘 创建硬盘的工具是bximage,这个工具在我们的Bochs目录下,使用命令行创建硬盘 第一个选择…

详解数据库、Hive以及Hadoop之间的关系

1.数据库: 数据库是一个用于存储和管理数据的系统。数据库管理系统(DBMS)是用于管理数据库的软件。数据库使用表和字段的结构来组织和存储数据。关系型数据库是最常见的数据库类型,使用SQL(Structured Query Language…

登录校验认证

会话技术 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。 会话跟踪: 一种维护浏览器状态的方法,服务器需要识别多次请…

【Web】浅聊Java反序列化之Rome——关于其他利用链

目录 前言 JdbcRowSetImpl利用链 BasicDataSource利用链 Hashtable利用链 BadAttributeValueExpException利用链 HotSwappableTargetSource利用链 前文:【Web】浅聊Java反序列化之Rome——EqualsBean&ObjectBean-CSDN博客 前言 Rome中ToStringBean的利用…

186基于matlab的信号盲源分离算法

基于matlab的信号盲源分离算法,包括变步长盲源分离(EASI),RLS(自然梯度和普通梯度),并将三种方法分离结果进行对比。程序已调通,可直接运行。 186 信号盲源分离算法 变步长盲源分离 (xiaohongshu.com)

结合大象机器人六轴协作机械臂myCobot 280 ,解决特定的自动化任务和挑战!(下)

Limo Pro 小车建图导航 引言 前景提要:我们在上文介绍了使用LIMO cobot 实现一个能够执行复杂任务的复合机器人系统的应用场景的项目,从以下三个方面:概念设计、系统架构以及关键组件。 本文主要深入项目内核的主要部分,同样也主要…

使用R语言进行聚类分析

一、样本数据描述 城镇居民人均消费支出水平包括食品、衣着、居住、生活用品及服务、通信、文教娱乐、医疗保健和其他用品及服务支出这八项指标来描述。表中列出了2016年我国分地区的城镇居民的人均消费支出的原始数据,数据来源于2017年的《中国统计年鉴》&#xf…

简单多状态dp问题----删除并获得点数

740. 删除并获得点数 - 力扣(LeetCode) 本题就是表示不能选值相邻的两个数。 假设nums [ 1,2,3,4,5,6],那么这其实就类似一个打家劫舍问题: 即选1,就不能选2,只能选3,4,5&#xff…

excel常用操作备忘

目录 快捷键基础数据透视图统计某列的值出现的频数 数据有效性数据分列运算符顺序文本匹配中的通配符错误的类型(常与IF嵌套使用)函数RANK(num, ref, [order])MID(str, start, len)逻辑函数混合函数选取整列AVERAGEIF(range, criteria, average_range)TR…

Flink 学习3 - 流处理API的基本转换算子 + 多流转换算子

流处理API-Transform 1、基本转换算子 map、flatMap、filter通常被统一称为基本转换算子(简单转换算子) DataStream 里没有 reduce 和 sum 这类聚合操作的方法,因为 Flink 设计中,所有数据必须先分组才能做聚合操作。 先 keyB…

ASUS华硕天选2锐龙版笔记本电脑FA506ICB/FA706IC原装出厂Windows11系统,预装OEM系统恢复安装开箱状态

链接:https://pan.baidu.com/s/122iHHEOtNUu4azhVPnxNuA?pwdsqk7 提取码:sqk7 适用型号: FA506IM、FA506IE、FA506IC、FA506IHR FA506IR、FA506IHRB、FA506ICB、FA506IEB FA706IM、FA706IE、FA706IC、FA706IHR FA706IR、FA706IHRB、F…

《Effective Modern C++》- 极精简版 15-21条

本文章属于专栏《业界Cpp进阶建议整理》 继续上篇《Effective Modern C》- 极精简版 5-14条。本文列出《Effective Modern C》的15-21条的个人理解的极精简版本。 Item15、尽量使用constexpr constexpr形容对象 constexpr对象都是const,但是const对象不一定是conste…

单数码管(arduino)

1.连接方法 挨个点亮每个灯 #include <Arduino.h>int pin_list[] {4, 5, 19, 21, 22, 2, 15, 18}; int num_pins sizeof(pin_list) / sizeof(pin_list[0]); // 计算数组中的元素数量void setup() {// 设置每个引脚为输出for(int i 0; i < num_pins; i) {pinMode(p…

ArcGIS学习(十三)多源数据下的城市街道功能评估

ArcGIS学习(十三)多源数据下的城市街道功能评估 本任务带来的内容是多元数据下的城市街道功能评估。本任务包括两个关卡: 城市街道空间中观解读 城市街道功能详细评价 首先,我们来看看本任务的分析思路。 1.城市街道空间中观解读 下面我们正式进入第一关的内容一- 城市…