文章目录

  • Redis 持久化
  • 一、RDB
    • 1.1 说明
    • 1.2 触发机制
      • 手动触发
      • 自动触发
    • 1.3 流程说明
    • 1.4 文件处理
    • 1.5 优缺点 & 适用场景
  • 二、AOF
    • 2.1 说明
    • 2.2 使用 AOF
    • 2.3 命令写入
    • 2.4 文件同步
    • 2.5 重写机制
    • 2.6 启动时数据恢复
    • 2.7 优缺点 & 适用场景
  • 三、不使用 AOF / RDB 的情况
    • 3.1 场景
    • 3.2 实现方案

Redis 持久化

Redis 本身是作用与内存中的数据库,所以必须考虑数据持久化问题(将内存中的数据存储到硬盘中)。

Redis 支持 RDB 与 AOF 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利用之前持久化的文件可以实现数据恢复。

在这里插入图片描述


一、RDB

1.1 说明

  1. RDB 持久化是 Redis 默认的持久化方式,通过 快照(snapshot)来持久化数据。
    • 即把当前进程数据生成快照保存到硬盘的过程、触发RDB持久化过程分为手动触发自动触发
  2. Redis 会在指定的时间间隔内生成数据的快照并保存在磁盘中(RDB 文件),通常是 .rdb 文件。(自动触发)、也可以手动执行命令进行手动触发

1.2 触发机制

手动触发

手动触发分别对应 savebgsave 命令:

  • SAVE:会阻塞 Redis 主进程,直到 RDB 持久化完成。这个命令会在当前进程中执行持久化操作,执行过程中 Redis 会暂停所有请求,直到数据保存完成。
    • 但是对于内存较大的实例会造成长时间阻塞,基本不采用。
  • BGSAVE :在后台异步执行RDB持久化,Redis 会生成一个子进程来执行持久化操作,主进程可以继续处理请求。执行 BGSAVE 时,Redis 会创建一个子进程来保存数据并生成 RDB 文件。
    • 阻塞只发生在 fork 阶段,一般时间很短。

Redis 内部所有涉及 RDB 的操作都类似 bgsave 的方式。

自动触发

Redis 运行自动触发 RDB 持久化机制,该机制在实际环境中更实用。

Redis 默认的 RDB 持久化是基于时间和写操作的触发条件。可以通过 redis.conf 配置文件中的 save 参数设置自动触发的条件。

  1. 使用 save 配置。如“save m n” 表示 m 秒内数据集发生了 n 次修改,自动 RDB 持久化。比如:

    save 900 1    # 900秒(15分钟)内至少有1次写操作时触发RDB
    save 300 10   # 300秒(5分钟)内至少有10次写操作时触发RDB
    save 60 10000 # 60秒内至少有10000次写操作时触发RDB
    
  2. 从节点进行全量复制操作时,主节点自动进行RDB持久化,随后将RDB文件内容发送给从节点。

  3. 执行 shutdown 命令关闭 Redis 时,执行 RDB 持久化。

比如在redis.conf的这个位置(内存管理)进行save配置:
在这里插入图片描述


1.3 流程说明

BGSAVE 是主流的 RDB 持久化方式,下图演示了其运作流程:

在这里插入图片描述

  1. 执行 bgsave 命令时,Redis 父进程首先会检查是否已有其他子进程正在执行,如 RDB 或 AOF 子进程。如果存在其他子进程,bgsave 命令将直接返回,不会执行。

  2. 父进程执行 fork 创建子进程,在 fork 过程中,父进程会阻塞。可以通过执行 INFO stats 命令并查看 latest_fork_usec 选项,获取最近一次 fork 操作的耗时,单位为微秒。

  3. fork 完成后,父进程不再阻塞,bgsave 命令返回 “Background saving started” 信息,表示子进程开始生成 RDB 文件,同时父进程可以继续处理其他命令。

  4. 子进程生成 RDB 文件,它会根据父进程的内存内容生成一个临时快照文件,并在完成后将原有文件替换为新生成的 RDB 文件。可以通过执行 lastsave 命令来获取最后一次成功生成 RDB 文件的时间,信息也会在 INFO 统计的 rdb_last_save_time 选项中显示。

  5. 子进程完成任务后,发送信号给父进程,通知父进程操作已完成。随后,父进程会更新相关的统计信息。


1.4 文件处理

  1. 保存:RDB 文件会保存在通过 dir 配置指定的目录中(默认目录为 /var/lib/redis/),文件名通过 dbfilename 配置指定(默认文件名为 dump.rdb)。可以通过执行 config set dir {newDir}config set dbfilename {newFilename} 动态修改目录和文件名设置。当 Redis 重启时,RDB 文件会保存到新的目录。

  2. 压缩:Redis 默认使用 LZF 算法对生成的 RDB 文件进行压缩处理,压缩后的文件体积远小于内存大小。默认情况下,压缩是开启的,可以通过 config set rdbcompression {yes|no} 动态修改压缩设置。

提示:虽然开启 RDB 压缩会消耗一定的 CPU 资源,但可以显著减小文件大小,方便将文件保存到硬盘或通过网络发送到从节点,因此建议开启压缩功能。

  1. 校验:如果 Redis 在启动时加载到损坏的 RDB 文件,启动会失败。此时,可以使用 Redis 提供的 redis-check-dump 工具检测 RDB 文件,并获取相应的错误报告。

1.5 优缺点 & 适用场景

优点:

  1. RDB 是一个紧凑压缩的二进制文件,代表 Redis 某个时间点上的数据快照,适用于备份、全量复制等场景。比如每6h执行 bgsave 备份,并把RDB文件复制到远程及其或者文件系统中(如hdfs)。
  2. Redis 加载 RDB 数据远快于 AOF。在重启Redis时恢复速度较快。
  3. RDB 文件是压缩格式,能够节省存储空间。

缺点:

  1. RDB 方式数据无法做到 实时持久化 / 秒级持久化。因为 bgsave 每次运行都会执行 fork 创建子进程,开销较大,频繁执行成本过高。
  2. RDB 文件使用特定二进制格式保存、Redis 版本演进过程中有多个 RDB 版本,兼容性可能存在风险。
  3. 数据丢失风险较大:RDB 是基于时间间隔的快照,如果在快照之间发生了 Redis 崩溃,则会丢失在最后一次快照之后的所有数据。

适用场景:

适合用于备份和灾难恢复,尤其是对于不要求非常实时的数据恢复场景。


二、AOF

2.1 说明

AOF(Append Only File)持久化:

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

AOF 文件中的内容是 Redis 执行的所有写命令的日志,这些命令可以用来重建数据库状态,目前已经是Redis持久化的主流方式。

2.2 使用 AOF

开启 AOF 功能需要设置配置:appendonly yes ,默认是不开启的。

在这里插入图片描述

AOF 文件名通过 appendfilename 配置指定,默认值为 appendonly.aof,其保存目录与 RDB 持久化方式一致,可通过 dir 配置进行设置。

AOF 的工作流程包括:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)。

AOF 工作流程如下图所示:
AOF 工作流程图

对上图工作流程的解释:

  1. 所有写入命令会被追加到 AOF 缓冲区(aof_buf)中。
  2. 根据配置的同步策略,AOF 缓冲区会定期将数据同步到硬盘。
  3. 随着 AOF 文件增大,Redis 会定期进行文件重写,以压缩文件并减小磁盘占用。
  4. 当 Redis 重启时,可以通过加载 AOF 文件来恢复数据。

2.3 命令写入

AOF 命令写入的内容是文本协议格式,如 set hello world,在AOF缓冲区中会追加的是:

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

此处遵守的是 Redis 格式协议,Redis 选择的是文本协议,可能有以下原因:

  1. 实现简单
    • 文本协议比二进制协议更加容易实现
  2. 简单性和可读性
    • 数据以纯文本的形式传输,格式简单且直观,用户可以很容易地查看和调试通信内容
  3. 兼容性
    • 文本协议的另一个优点是它具有较高的跨平台兼容性。所有主流的操作系统和编程语言都可以轻松地处理文本数据

AOF 过程中为什么需要 aof_buf 缓冲区?

  • 我们知道,Redis使用单线程响应命令,如果每次写 AOF 文件都直接同步硬盘,从内存的读写变为IO读写,性能必然下降。先写入缓冲区可以有效减少 IO 次数,同时 Redis 还可以提供多种缓冲区策略,让用户根据自己的需求做出合理的平衡。

2.4 文件同步

Redis 提供了多种 AOF 缓冲区同步文件策略,使用参数 appendfsync 控制。不同配置值的含义如下表所示:

表 4-1 AOF 缓冲区同步文件策略

可配置值说明
always每次命令写入 aof_buf 后都调用 fsync 同步,完成后返回。
everysec命令写入 aof_buf 后执行 write 操作,不进行 fsync。每秒由同步线程执行 fsync
no命令写入 aof_buf 后执行 write 操作,由操作系统控制 fsync 的频率。

系统调用 writefsync 的说明

  • write 操作:触发延迟写(delayed write)机制。Linux 内核使用页缓冲区提高硬盘 I/O 性能。write 操作将数据写入系统缓冲区后立即返回,实际的硬盘同步依赖系统调度机制,例如缓冲区满或达到时间周期。若系统发生故障或宕机,未同步的数据可能丢失。
  • fsync 操作:对单个文件进行强制硬盘同步,直到数据写入硬盘前,fsync 会阻塞。

配置说明

  • always 配置:每次写入时都会同步 AOF 文件,性能较差。在普通的 SATA 硬盘上,通常只能支持几百 TPS 写入。除非数据至关重要,否则不推荐使用此配置。
  • no 配置:由于操作系统同步策略不可控,性能较高,但数据丢失的风险大增。除非数据不重要,否则不推荐使用。
  • everysec 配置:为默认配置,也是推荐配置,兼顾了数据安全性与性能。理论上最多丢失 1 秒的数据,适用于大多数场景。

2.5 重写机制

随着 Redis 持续将命令写入 AOF 文件,文件体积会不断增大。为了优化存储和性能,Redis 引入了 AOF 重写机制,它会压缩 AOF 文件的体积。

AOF 重写的过程是将 Redis 进程内的数据转换为写命令,并同步到新的 AOF 文件中。

为什么重写后的 AOF 文件会变小? 主要原因如下:

  • 剔除超时数据:进程内已经超时的数据不会写入重写后的文件。
  • 删除无效命令:旧 AOF 文件中的无效命令(如 delhdelsrem 等)会在重写时被删除,仅保留数据的最终状态。
  • 合并多个写操作:多个连续的写操作可以合并成一条命令。例如,lpush list alpush list blpush list c 可以合并为 lpush list a b c

重写后的 AOF 文件较小,既降低了硬盘的空间占用,又能提高 Redis 启动时的数据恢复速度。

AOF 重写过程可以通过手动和自动两种方式触发:

  • 手动触发:使用 bgrewriteaof 命令。
  • 自动触发:根据 auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage 参数自动触发重写。
    • auto-aof-rewrite-min-size:定义触发重写时 AOF 文件的最小大小,默认为 64MB。
    • auto-aof-rewrite-percentage:定义当前 AOF 文件大小相对于上次重写时增加的比例。

在这里插入图片描述

AOF 重写的执行流程:

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

  2. 父进程执行 fork 创建子进程
    父进程会通过 fork 创建子进程进行重写操作。

  3. 重写过程

    • a. 父进程在 fork 后继续响应其他命令,所有修改操作都会写入 AOF 缓冲区,并根据 appendfsync 策略同步到硬盘,确保旧 AOF 文件的数据完整性。
    • b. 子进程只有在 fork 之前的内存数据,父进程中的修改操作会被写入 AOF 重写缓冲区。
  4. 子进程重写 AOF 文件
    子进程根据内存快照,将命令合并并写入新的 AOF 文件中。

  5. 完成重写

    • a. 子进程写入新文件后,发送信号给父进程。
    • b. 父进程将 AOF 重写缓冲区内临时保存的命令追加到新 AOF 文件中。
    • c. 父进程用新生成的 AOF 文件替换旧的 AOF 文件。

通过上述重写机制,Redis 能有效优化 AOF 文件的体积,提升性能并减少存储消耗。


2.6 启动时数据恢复

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

在这里插入图片描述


2.7 优缺点 & 适用场景

优点:

  1. AOF 可以实现更高的持久化安全性,相比于 RDB,它更能保证数据不丢失。
  2. 如果 Redis 崩溃,可以从 AOF 文件恢复到最后一个写操作。
  3. 可设置不同的同步策略,以实现平衡的性能和持久化保障。

缺点:

  1. AOF 文件比 RDB 文件更大,因为它记录的是每个写操作的日志,可能会占用更多磁盘空间。
  2. 写操作会稍微慢一些,因为每次写入命令都要追加到 AOF 文件中,虽然可以通过异步写入来缓解性能问题。
  3. AOF 恢复数据时的速度较慢,因为需要重放所有写命令。

适用场景:

AOF 适合用于要求较高数据持久性的场景,例如需要尽量避免数据丢失的应用。


三、不使用 AOF / RDB 的情况

3.1 场景

在实际业务场景下,如果不使用 AOF 或 RDB,Redis 可以与 MySQL 等外部数据库结合,来实现数据的持久化。这种方案通常适用于以下情况:

  1. 缓存加速 + 持久化分离

    • 特点
      • Redis 作为高性能缓存,MySQL 作为真实数据源。
      • 适合读多写少的业务(如商品详情页、用户画像)。
    • 同步策略
      • 读:优先读 Redis,未命中则查 MySQL 并回填。
      • 写:直接写 MySQL,并删除/更新 Redis 缓存(Cache-Aside 模式)。
  2. 临时数据 + 永久存储分离

    • 特点
      • Redis 存储短期高频数据(如会话、排行榜),MySQL 存储长期数据。
      • 适合时效性数据(如 30 天内的订单状态)。
    • 同步策略
      • 通过 TTL 自动清理 Redis 数据,关键数据异步归档到 MySQL。
  3. 高并发写入缓冲

    • 特点
      • 用 Redis 缓冲突发写入(如秒杀库存),再平滑同步到 MySQL。
      • 适合写密集型业务(如点击计数、日志采集)。
    • 同步策略
      • Redis 累加计数,每小时同步一次聚合结果到 MySQL。

3.2 实现方案

  1. 双写模式(Write-Through)

    • 机制
      应用同时写入 Redis 和 MySQL,保持双数据源一致。
      def set_user(user_id, data):# 同步写 MySQLmysql.execute("REPLACE INTO users VALUES (%s, %s)", (user_id, data))# 写 Redisredis.set(f"user:{user_id}", data)
      
    • 优点:强一致性
    • 缺点:写入性能下降,需处理事务回滚(如 MySQL 失败需回滚 Redis)。
  2. 异步同步(Write-Behind)

    • 机制
      先写 Redis,再通过消息队列或定时任务异步同步到 MySQL。
      def set_user(user_id, data):redis.set(f"user:{user_id}", data)# 发送到消息队列(如 Kafka/RabbitMQ)mq.publish("user_update", {"id": user_id, "data": data})# 消费者异步处理 MySQL 写入
      
    • 优点:高性能,解耦
    • 缺点:存在短暂不一致窗口。
  3. 定时批量同步

    • 机制
      定期扫描 Redis 数据批量写入 MySQL(适合冷数据)。
      -- MySQL 表设计示例
      CREATE TABLE redis_backup (`key` VARCHAR(255) PRIMARY KEY,`value` TEXT,`expire_time` DATETIME
      );
      

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

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

相关文章

Python 企业级开发与DevOps实践

https://www.python.org/static/community_logos/python-logo-master-v3-TM.png 大型项目结构与设计模式 项目结构规范 text 复制 下载 enterprise_app/ ├── docs/ # 项目文档 ├── tests/ # 测试代码 │ ├── unit/ …

E结构体基础.go

前言:结构体是一种用户自定义的数据类型,它可以将多个不同类型的数据整合在一起,形成一个有机的整体。这就好比在现实生活中,我们有各种各样的物品,它们各自有不同的属性和用途,而结构体就像是一个收纳箱&a…

Spring @Autowired 依赖注入全解析

Autowired 是 Spring 框架中实现依赖注入的核心注解,其自动装配过程可分为以下步骤,结合了类型匹配、名称解析和容器协作机制: 1. 组件扫描与 Bean 定义注册 扫描阶段:Spring 容器启动时,通过 ComponentScan 或 XML 配…

将git的普通目录用idea初始化为maven项目

在 IntelliJ IDEA 中将一个已存在的 Git 目录初始化为 Maven 项目,可以通过以下步骤完成。这些步骤假设你已经有一个包含代码的 Git 仓库,并希望将其转换为 Maven 项目结构,以便更好地管理依赖和构建。 步骤 1:打开或导入 Git 仓库…

Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建

一、key 属性的核心作用 在 Vue 中,key是一个特殊的属性,主要用于协助 Vue 的虚拟 DOM(Virtual DOM)算法高效地更新实际 DOM。它的核心作用可以概括为: 唯一标识节点:为每个节点提供一个唯一的身份标识优化 Diff 算法:帮助 Vue 准确判断两个节点是否为同一节点(如for循…

【音视频】PJSIP库——示例简介、C++类说明

1、简介 pjsip库的源码中有很多示例,是入门pjsip的第一手资料,下面将各个示例所演示的功能列举出来,以便下一步学习; 最后总结下C++接口主要类及成员函数说明。 2、示例介绍 2.1 音视频处理 aectest 音频回声消除测试工具,用于演示音频处理模块中的回声消除(AEC)功能…

网站用CDN可以防DDoS和CC攻击吗?

现在市面上常见有两种CDN,加速CDN与高防CDN,这两种的区别还是很大的。 加速CDN: 加速CDN基本上都是共享、无防节点,主要做的是加速,所以价格也会相对较低,大陆地区的CDN都需要备案域名接入使用。 高防CD…

【图片识别改名】批量识别图片中的文字对图片进行改名,识别文字对图片重新命名的操作步骤和注意事项

一、应用场景 快递单号识别与管理:在快递业务中,每天会产生大量的快递面单图片。通过咕嘎OCR批量识别面单上的快递单号等关键信息,并以此对图片进行重命名,方便工作人员快速查询和管理快递包裹的物流信息,提高快递处理…

先理解软件工程,再谈AI辅助研发

摘要: 近期行业内对“AI赋能软件工程”的讨论,大多聚焦于代码生成等局部提效,这是一种危险的短视。本文旨在纠正将“软件开发”等同于“编码”的普遍误解,深入探讨软件工程的系统性本质。我们将论证,若缺乏坚实的工程体…

Android软件适配遥控器需求-案例经验分享

不分大屏产品需要有遥控器功能,这里分享部分实战经验 文章目录 前言一、案例部分效果图二、项目基础架构三、焦点基础知识适配遥控器基础-焦点问题焦点管理明确焦点状态布局实现硬编码实现引入第三方自定义组件实现 焦点顺序作用 初始焦点 requestFocus 按键处理获取…

《HTTP权威指南》 第3章 HTTP报文

报文是如何流动的 HTTP报文是在HTTP程序之间发送的数据块。数据块以一些文本形式的元信息开头。 报文方向有:流入、流出、上游、下游。 流入和流出描述事务处理的方向,流入和流出是基于服务器的描述。 流入:客户端发往服务器的请求报文 流…

Kafka 集群架构与高可用方案设计(二)

Kafka 集群架构与高可用方案的优化策略 合理配置参数 在 Kafka 集群的配置中,参数的合理设置对于系统的高可用性和性能表现起着关键作用。例如,min.insync.replicas参数定义了 ISR(In-Sync Replicas,同步副本)集合中…

47-Oracle ASH报告解读

上一期生成了ASH报告后,就需要解读报告关键信息。ASH的使用可以快速定位瞬时性能问题。生产环境的场景时间紧、任务重,但是必须要结合具体业务分析,同时借助其他工具做报告做趋势分析。 一、ASH 技术原理​ ​1. 核心机制​ ​采样原理​&a…

“本地化思维+模块化体验”:一款轻量数据中心监控系统的真实测评

“本地化思维模块化体验”:一款轻量数据中心监控系统的真实测评 在数据中心运维逐步精细化的今天,一款真正贴合本地用户习惯、设计有温度的系统并不多见。近期体验了一款功能全面、逻辑清晰的监控平台,给人留下了深刻印象。并不是广。今天就从…

词编码模型有哪些

词编码模型有哪些 词编码模型在高维向量空间的关系解析与实例说明 如Word2Vec、BERT、Qwen等 一、高维向量空间的基础概念 词编码模型(如Word2Vec、BERT、Qwen等)的核心是将自然语言符号映射为稠密的高维向量,使语义相近的词汇在向量空间中位置接近。以Qwen模型为例,其…

elementui el-select 获取value和label 以及 对象的方法

获取 el-select 的 value 和 label 值 在 Element UI 的 el-select 组件中,可以通过以下方法获取选项的 value 和 label 值。 1、绑定 v-model 获取 value el-select 通常通过 v-model 绑定 value 值,直接访问绑定的变量即可获取当前选中的 value。…

树莓派与嵌入式系统实验报告

一、Linux 系统编译工具链实践:mininim 源码编译 虚拟机 Ubuntu 编译流程 环境配置问题 编译时遇到虚拟机无法联网的情况,通过连接个人热点解决(校园网限制导致无法访问外部资源)。 执行 ./bootstrap 时报错 gnulib-tool: command…

IDEA部署redis测试

新建springboot,项目改为:testredis E:\ideaproject\testredis\src\main\java\org\example\testredis\TestredisApplication.java 代码为: package org.example.testredis;import org.springframework.boot.SpringApplication; import org.…

旅游服务礼仪实训室:从历史演进到未来创新的实践探索

一、旅游服务礼仪实训室的历史演进:从礼制规范到职业化培养 旅游服务礼仪实训室的建设并非一蹴而就,其发展历程与人类对礼仪认知的深化及职业教育体系的完善密切相关。 1. 古代礼仪教育的萌芽 礼仪作为社会行为规范,最早可追溯至中国夏商周…

Could not find a declaration file for module ‘..XX‘.

1. 添加 Vue 声明文件 如果您还没有为 .vue 文件创建类型声明,可以通过创建一个新的类型声明文件来解决该问题。 步骤: 在您的项目根目录下创建一个名为 shims-vue.d.ts 的文件(您可以选择其他名称,但建议使用常见名称以便于识…