【Redis】持久化操作详解
Redis 持久化操作详解
Redis 实现持久化的时候,具体是按照什么样的策略来实现的呢?
Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式,两种持久化方式可以单独使用其中一种,也可以将这两种方式结合使用。
- RDB(Redis DataBase):根据指定的规则将内存中的数据定期备份存储在硬盘上,
- AOF(Append Only File):每次执行命令后将命令本身记录下来,实时备份。
一、RDB 持久化
1.1 RDB 原理
RDB 持久化是通过生成数据快照(Snapshot)的方式,将 Redis 内存中的数据写入到磁盘上的二进制文件中。这个文件被称为 RDB 文件。RDB 文件可以在 Redis 重启时用于恢复数据。
Redis 提供了两种生成 RDB 文件的命令:SAVE
和 BGSAVE
。
SAVE
命令:在主线程中执行生成 RDB 文件的操作。由于 ,由于和执行操作命令在同一个线程,如果写入 RDB 文件的时间太长,中会阻塞主线程BGSAVE
命令:创建一个子进程来生成 RDB 文件,这样可以避免了阻塞主线程的情况
重点介绍一下:BGSAVE的工作流程
Redis的BGSAVEe工作流程是通过创建子进程来实现异步生成快照。在这个过程中,Redis使用了写时复制(copy-on-write)技术,它的核心思想是在主进程发生写操作时,会将相关的内存页复制一份,然后交给子进程使用,而主进程则继续进行正常的读写操作。这样可以保证只有在出现需要变更的数据时才进行数据复制,从而减少额外内存消耗和提高性能。
当执行BGSAVE命令时,Redis会创建一个子进程来执行实际的持久化工作,同时父进程继续处理客户端的其他请求。子进程会将数据写入内存的临时文件中,使用写时复制技术来保证数据的一致性。在生成RDB文件的过程中,只有当发生需要变更的数据时才进行内存页的复制,从而避免内存的额外占用。
1.2 RDB 自动化配置
Redis 可以通过配置文件的选项来实现自动化的 RDB 持久化,
配置文件位置一般:
具体配置如下:
save 900 1
save 300 10
save 60 10000
别看选项名叫 save,实际上执行的是 bgsave 命令,也就是会创建子进程来生成 RDB 快照文件。开启之后,RDB的目录一般默认:/var/lib/redis(可以自行配置的)
只要满足上面条件的任意一个,就会执行 bgsave,它们的意思分别是:
- 900 秒之内,对数据库进行了至少 1 次修改;
- 300 秒之内,对数据库进行了至少 10 次修改;
- 60 秒之内,对数据库进行了至少 10000 次修改。
只要满足以上任一条件,Redis 就会执行一次 BGSAVE
操作。
Redis 的 RDB(Redis Database)快照是全量快照,每次执行时都会将内存中的所有数据记录到磁盘。如果设置频率太高则会让成本变高,负载较重,频繁执行会影响 Redis 的性能,而设置的频率太低则会在服务器故障时导致更多数据丢失。通常,RDB 快照至少设置为每 5 分钟保存一次,以在性能和数据丢失风险之间取得平衡。与 AOF(Append Only File)持久化相比,RDB 快照在故障时可能丢失更多数据,因为 AOF 可以每秒记录操作,减少数据丢失。
如果 Redis 服务器宕机,在使用 RDB 快照时,系统会丢失自上次快照以来的所有数据。例如,如果快照每 5 分钟执行一次,宕机时最多可能会丢失 5 分钟的数据。
1.3 RDB 的优缺点
优点:
- 数据恢复速度快:RDB 文件是紧凑的二进制文件,加载速度很快。
- 占用磁盘空间小:RDB 文件经过压缩,占用的磁盘空间较少。
- 适合大数据恢复:在数据量较大时,RDB 文件的加载速度要比 AOF 快得多。
缺点:
- 数据丢失风险较高:由于 RDB 是定期快照,如果 Redis 在两次快照之间发生故障,所有在此期间的数据修改将会丢失。
- 频繁快照对性能的影响:频繁执行
BGSAVE
操作会导致额外的磁盘 I/O 操作和 CPU 资源消耗。
1.4 RDB 快照期间的数据修改
在执行 BGSAVE
过程中,Redis 仍然可以继续处理写操作。这是通过写时复制技术(Copy-On-Write, COW)实现的。当 BGSAVE
命令执行时,Redis 会通过 fork()
创建一个子进程,子进程与主进程共享相同的内存数据。只有在修改数据时,才会将被修改的数据复制一份,从而主进程可以继续处理新的写操作,而子进程可以继续读取原来的数据进行 RDB 快照。
Redis 的 BGSAVE
机制通过创建子进程在后台执行数据快照,有效地减少了创建子进程时的性能损耗,并避免了阻塞主线程。子进程与父进程共享内存数据,使得子进程可以直接读取并写入 RDB 文件,而不会影响主线程的只读操作。然而,一旦主线程需要修改共享数据,就会触发写时复制机制,复制数据副本供主线程修改,而子进程继续使用原始数据进行快照。这意味着在快照过程中主线程的修改不会即时反映到 RDB 文件中,存在数据丢失的风险。此外,极端情况下,频繁的写操作可能导致内存占用翻倍,因此在写操作密集的场景中,需要密切监控内存使用,以防止内存耗尽。总之,bgsave 提供了一种高效的数据持久化方式,但同时也需要谨慎管理内存资源和考虑数据一致性问题。
1.5 RDB 实践示例
在实际应用中,可以通过以下命令和配置来实现 RDB 持久化:
-
在命令行中,手动生成 RDB 快照:
SAVE
或
BGSAVE
-
配置文件设置自动生成 RDB 快照:
save 900 1 save 300 10 save 60 10000
二、AOF 持久化
2.1 AOF 原理
AOF(Append Only File)持久化通过记录每次写操作的日志来实现数据的持久化。Redis 将每次写操作(例如 SET
、INCR
等)记录到 AOF 文件中,当 Redis 重启时,可以通过重放 AOF 文件中的写操作来恢复数据。
AOF 的⼯作流程操作:命令写⼊(append)、⽂件同步(sync)、⽂件重写(rewrite)、重启加载(load)
在 Redis 中 AOF 持久化功能默认是不开启的,需要我们修改 redis.conf
配置文件中的以下参数:
开启之后,所在的位置和RDB的目录一样:/var/lib/redis(可以自行配置的)
AOF 文件是纯文本文件,包含了所有修改 Redis 数据的命令。Redis 提供了三种不同的同步策略来控制 AOF 文件的写入频率:
appendfsync always
:每次有数据修改时都同步到 AOF 文件,性能最差但数据最安全。appendfsync everysec
:每秒同步一次 AOF 文件,性能和数据安全性之间的折中方案。appendfsync no
:由操作系统决定何时同步 AOF 文件,性能最好但数据安全性最差。
写回策略 | 写回时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步写回 | 可靠性高、最大程度保证数据不丢失 | 性能开销大 |
Everysec | 每秒写回 | 性能适中 | 宕机时会丢失1秒内的数据 |
No | 由操作系统控制写回 | 性能好 | 宕机时丢失的数据可能会很多 |
2.2 AOF 重写
随着时间的推移,AOF 文件会不断增长,为了避免文件过大,Redis 提供了 AOF 重写机制。AOF 重写通过创建一个新的 AOF 文件,包含相同的数据但体积更小。
AOF 重写是在后台通过创建子进程来完成的,不会阻塞主线程。
重写过程如下:
- 创建一个子进程。
- 子进程读取当前的数据库快照,并将其写入到新的 AOF 文件中。
- 主线程继续记录新的写操作到重写缓冲区中。
- 重写完成后,将重写缓冲区中的写操作追加到新的 AOF 文件中。
- 用新的 AOF 文件替换旧的 AOF 文件。
在Redis执行AOF重写(AOF rewrite)过程中,子进程负责创建新的AOF文件,而父进程则继续处理客户端请求,并将新请求产生的AOF数据写入到缓冲区,随后刷新到原有的AOF文件中。子进程在创建时继承了父进程的内存状态,因此其内存数据反映了父进程fork操作之前的状态。对于fork之后父进程接收的新请求及其对内存的修改,子进程并不知情。为此,父进程额外设置了一个名为aofrewrite_buf的缓冲区,专门用于存放fork之后接收的数据。当子进程完成新AOF文件的写入后,会通过信号通知父进程,父进程随后将aofrewrite_buf缓冲区中的内容追加到新AOF文件中。这一过程完成后,新的AOF文件将取代旧的AOF文件,确保数据的完整性和一致性。
那么是如何让原本的数据但体积更小
重写机制的妙处在于,尽管某个键值对被多条写命令反复修改,最终也只需要根据这个「键值对」当前的最新状态,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这样就减少了 AOF 文件中的命令数量。最后在重写工作完成后,将新的 AOF 文件覆盖现有的 AOF 文件。
2.3 AOF 的优缺点
优点:
- 数据持久性高:AOF 可以记录每个写操作,通过适当的同步策略,几乎可以实现秒级的数据持久性。
- 可读性好:AOF 文件是纯文本文件,可以很方便地查看和编辑。
- 适合频繁写操作:由于 AOF 是记录每次写操作,不会像 RDB 那样生成大文件,因此适合频繁写操作的场景。
缺点:
- 文件体积大:相比 RDB,AOF 文件会更大,因为它记录了所有的写操作。
- 恢复速度较慢:重放 AOF 文件中的写操作来恢复数据,速度比加载 RDB 文件要慢。
2.4 AOF 实践示例
在实际应用中,可以通过修改配置文件:
-
开启 AOF 持久化:
appendonly yes
-
配置 AOF 同步策略:
appendfsync everysec
-
手动触发 AOF 重写:
BGREWRITEAOF
三、混合持久化
尽管 RDB 比 AOF 的数据恢复速度快,但是快照的频率不好把握:
- 如果频率太低,两次快照间一旦服务器发生宕机,就可能会比较多的数据丢失;
- 如果频率太高,频繁写入磁盘和创建子进程会带来额外的性能开销。
那有没有什么方法不仅有 RDB 恢复速度快的优点和,又有 AOF 丢失数据少的优点呢?
当然有,那就是将 RDB 和 AOF 合体使用,这个方法是在 Redis 4.0 提出的,该方法叫混合使用 AOF 日志和内存快照,也叫混合持久化。
如果想要开启混合持久化功能,可以在 Redis 配置文件将下面这个配置项设置成 yes:
aof-use-rdb-preamble yes
混合持久化工作在 AOF 日志重写过程。
当开启了混合持久化时,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。
也就是说,使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。
相关文章:

【Redis】持久化操作详解
Redis 持久化操作详解 Redis 实现持久化的时候,具体是按照什么样的策略来实现的呢? Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式,两种持久化方式可以单独使用其中一种&…...

C#调用HttpClient.SendAsync报错:System.Net.Http.HttpRequestException: 发送请求时出错。
C#调用HttpClient.SendAsync报错:System.Net.Http.HttpRequestException: 发送请求时出错。 var response await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);问题出在SSL/TLS,Windows Server 2012不支持…...

大模型基础知识
文章目录 1. 位置编码1.1 绝对位置编码1.2 相对位置编码1.3 旋转位置编码2. 注意力机制2.1 MHA(muti head attention)2.2 MQA(muti query attention)2.3 GQA(grouped query attention)3. 大模型分类4. 微调方法4.1 Prompt Tuning4.2 Prefix Tuning4.3 Lora4.4 QLora5. La…...

时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)
目录 引言 LSTM的预测效果图 LSTM机制 了解LSTM的结构 忘记门 输入门 输出门 LSTM的变体 只有忘记门的LSTM单元 独立循环(IndRNN)单元 双向RNN结构(LSTM) 运行代码 代码讲解 引言 LSTM(Long Short-Term Memory)是一种常用的循环神经网络&a…...

[8] CUDA之向量点乘和矩阵乘法
CUDA之向量点乘和矩阵乘法 计算类似矩阵乘法的数学运算 1. 向量点乘 两个向量点乘运算定义如下: #真正的向量可能很长,两个向量里边可能有多个元素 (X1,Y1,Z1) * (Y1,Y2,Y3) X1Y1 X2Y2 X3Y3这种原始输入是两个数组而输出却缩减为一个(单一值)的运…...

音视频开发9 FFmpeg 解复用框架说明,重要知识点
一,播放器框架 二 常用音视频术语 容器/文件(Conainer/File): 即特定格式的多媒体文件, 比如mp4、flv、mkv等。 媒体流(Stream): 表示时间轴上的一段连续数据࿰…...

抖音小店出单之后怎么发货?抖店详细发货流程来了
大家好,我是喷火龙。 抖音小店发货是有规则的,如果出现超时发货或者虚假发货都会被平台处罚的,会影响我们店铺的评分和正常运营,还有些小伙伴们在发货的时候会遇到平台的违规提醒等问题。 今天我就给大家讲一下抖音小店的发货流…...
Transformer详解(5)-编码器和解码器
1、Transformer编码器 import torch from torch import nn import copy from norm import Norm from multi_head_attention import MultiHeadAttention from feed_forward import FeedForward from pos_encoder import PositionalEncoderdef get_clones(module, N):"&quo…...
线程安全-3 JMM
一.谈一下JMM 1.JMM,JavaMemoryModel,Java内存模型。定义了多线程对共享内存读写操作的行为规范,通过规范多线程对共享内存的读写操作,以保证指令执行和结果的正确性。 2.JMM把内存分为两块 (1)主内存&a…...
4 CSS的 变换、过渡与动画
CSS3引入了变换、过渡和动画特性,使得网页可以呈现出丰富的视觉效果和交互体验。通过这些新特性,开发者可以创建复杂的动画效果,而不需要使用JavaScript。 4.1 变换(Transforms) 变换允许开发者对元素进行旋转、缩放…...
前端基础入门三大核心之JS篇:掌握数字魔法 ——「累加器与累乘器」的奥秘籍【含样例代码】
前端基础入门三大核心之JS篇:掌握数字魔法 ——「累加器与累乘器」的奥秘籍 🧙♂️ 基础概念:数字的魔杖与炼金术累加器(Accumulator)累乘器(Multiplier) 📚 实战演练:…...
git clone 出现的问题
问题: core源码ref新API % git clone https://github.com/xxxx.git Cloning into core... remote: Enumerating objects: 58033, done. remote: Counting objects: 100% (1393/1393), done. remote: Compressing objects: 100% (750/750), done. error: 432 bytes of body are …...

Vue2和Vue3生命周期的对比
Vue2和Vue3生命周期的对比 Vue2 和 Vue3 生命周期对照表Vue2 和 Vue3 生命周期图示 Vue2 和 Vue3 生命周期对照表 触发时机Vue2.xVue3.x组件创建时运行beforeCreate setup createdsetup 挂载在DOM时运行beforeMountonBeforeMountmountedonMounted响应数据修改时运行beforeUpdat…...

全面解析Java.lang.ClassCastException异常
全面解析Java.lang.ClassCastException异常 全面解析Java.lang.ClassCastException异常:解决方案与最佳实践 🚀📚摘要引言1. 什么是Java.lang.ClassCastException?代码示例 2. 报错原因2.1 类型不兼容2.2 泛型类型擦除2.3 接口和实…...

美团Java社招面试题真题,最新面试题
如何处理Java中的内存泄露? 1、识别泄露: 使用内存分析工具(如Eclipse Memory Analyzer Tool、VisualVM)来识别内存泄露的源头。 2、代码审查: 定期进行代码审查,关注静态集合类属性和监听器注册等常见内…...

二十八、openlayers官网示例Data Tiles解析——自定义绘制DataTile源数据
官网demo地址: https://openlayers.org/en/latest/examples/data-tiles.html 这篇示例讲解的是自定义加载DataTile源格式的数据。 先来看一下什么是DataTile,这个源是一个数组,与我们之前XYZ切片源有所不同。DataTile主要适用于需要动态生成…...

分布式事务解决方案(最终一致性【TCC解决方案】)
最终一致性分布式事务概述 强一致性分布式事务解决方案要求参与事务的各个节点的数据时刻保持一致,查询任意节点的数据都能得到最新的数据结果,这就导致在分布式场景,尤其是高并发场景下,系统的性能受到了影响。而最终一致性分布式…...

App Inventor 2 Encrypt.Security 安全性扩展:MD5哈希,SHA/AES/RSA/BASE64
这是关于App Inventor和Thunkable安全性的扩展,它提供MD5哈希,SHA1和SHA256哈希,AES加密/解密,RSA加密/解密,BASE64编码/解码方法。 权限 此扩展程序不需要任何权限。 事件 OnErrorOccured 抛出任何异常时将触发此事件…...

深入了解Linux中的环境变量
在Linux系统中,环境变量(Environment Variables)是用于配置操作系统和应用程序运行环境的一种机制。它们储存在键值对中,可以控制程序的行为、路径查找和系统配置。本文将深入探讨环境变量的基本概念、常见类型、设置和管理方法&a…...

雷军-2022.8小米创业思考-8-和用户交朋友,非粉丝经济;性价比是最大的诚意;新媒体,直播离用户更近;用真诚打动朋友,脸皮厚点!
第八章 和用户交朋友 2005年,为了进一步推动金山的互联网转型,让金山的同事更好地理解互联网的精髓,我推动了一场向谷歌学习的运动,其中一个小要求就是要能背诵“谷歌十诫”。 十诫的第一条就令人印象深刻:以用户为中…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...