Redis如何做持久化的?能说一下RDB和AOF的实现原理吗?
mhr18 2025-03-23 21:09 26 浏览 0 评论
我们来详细讲解一下 Redis 的持久化机制,以及 RDB 和 AOF 两种持久化方式的实现原理。
为什么需要持久化?
Redis 是一个内存数据库,所有数据都存储在内存中,这使得 Redis 拥有极高的读写性能。但是,内存中的数据是非持久化的,一旦 Redis 服务器宕机或重启,内存中的数据就会丢失。
为了解决数据丢失的问题,Redis 提供了持久化机制,将内存中的数据写入到磁盘中,这样即使服务器重启,也能从磁盘中恢复数据。
Redis 提供的两种持久化方式:
Redis 提供了两种主要的持久化方式:
- RDB (Redis DataBase):快照持久化
- AOF (Append Only File):追加文件持久化
你可以单独使用其中一种,也可以同时使用两种方式。
1. RDB (快照持久化)
概念:
RDB 持久化是指在指定的时间间隔内,将 Redis 在内存中的数据集快照写入到磁盘中,生成一个 RDB 文件。这个 RDB 文件是二进制文件,包含了某个时间点 Redis 所有的数据。
实现原理:
RDB 持久化可以通过两种命令手动触发,也可以通过 Redis 的配置自动触发:
- 手动触发:
- SAVE 命令:同步执行快照,会阻塞 Redis 服务器,直到 RDB 文件创建完成。在快照过程中,Redis 无法处理任何客户端请求。生产环境不建议使用 SAVE 命令,因为它会造成 Redis 服务不可用。
- BGSAVE 命令:异步执行快照,Redis 会 fork 一个子进程来执行快照操作,主进程仍然可以继续处理客户端请求。生产环境推荐使用 BGSAVE 命令。
- 自动触发:
- 通过在 redis.conf 配置文件中设置 save 指令,可以配置 Redis 在满足一定条件时自动执行 BGSAVE 命令。例如:
- 复制代码
- save 900 1 # 900 秒内,如果至少有 1 个 key 被修改,则执行 BGSAVE save 300 10 # 300 秒内,如果至少有 10 个 key 被修改,则执行 BGSAVE save 60 10000 # 60 秒内,如果至少有 10000 个 key 被修改,则执行 BGSAVE 你可以配置多个 save 指令,只要满足其中一个条件,就会触发 BGSAVE。
BGSAVE 命令的详细执行过程:
- 客户端发送 BGSAVE 命令或满足自动触发条件时,Redis 主进程接收到请求。
- Redis 主进程调用 fork() 系统调用创建出一个子进程。 fork() 是一个重要的系统调用,它会创建一个与父进程几乎完全相同的子进程,子进程会复制父进程的内存空间(数据段、堆栈段等),但代码段是共享的。
- 子进程负责将内存中的数据写入到临时的 RDB 文件中。 由于使用了 fork() 的 写时复制 (Copy-On-Write, COW) 技术,在子进程创建 RDB 文件的过程中,如果主进程需要修改数据,并不会立即复制整个内存空间,而是只复制需要修改的数据页 (page)。这样可以尽量减少内存的复制开销,提高效率。
- 子进程完成 RDB 文件创建后,将临时 RDB 文件替换旧的 RDB 文件 (通常是 dump.rdb)。
- 子进程退出,主进程继续处理客户端请求。
RDB 文件的结构:
RDB 文件是一个二进制文件,其结构大致如下:
- Redis 版本信息: 记录生成 RDB 文件的 Redis 版本号,用于兼容性处理。
- 数据库信息: 包含多个数据库 (DB) 的数据。每个数据库又包含:数据库编号: 标识数据库的索引。键值对数据: 存储数据库中的所有键值对。每个键值对包含:键 (Key): 字符串类型。值 (Value): 可以是 String, List, Set, Hash, Sorted Set 等 Redis 支持的数据类型。过期时间 (可选): 如果键设置了过期时间,则会记录过期时间戳。
- EOF 标识: 文件结束标识。
- 校验和 (CRC64): 用于校验 RDB 文件的完整性。
RDB 的优点:
- 紧凑性: RDB 文件是二进制压缩文件,体积小,非常适合备份和恢复。
- 恢复速度快: RDB 文件包含了某个时间点的完整数据快照,恢复数据时只需要加载 RDB 文件到内存即可,恢复速度比 AOF 快。
- 对性能影响小: BGSAVE 命令通过子进程进行快照,主进程几乎不受影响,可以继续处理客户端请求。
RDB 的缺点:
- 数据丢失风险: RDB 是定时快照,如果在两次快照之间 Redis 服务器宕机,那么这段时间内的数据将会丢失。数据丢失的量取决于快照的频率。
- fork() 开销: BGSAVE 命令需要 fork() 子进程,如果数据集非常大,fork() 过程可能会比较耗时,并且在 fork() 期间,主进程可能会有一定的阻塞。
2. AOF (追加文件持久化)
概念:
AOF 持久化是指将 Redis 服务器执行的每个写命令(例如 SET, HSET, SADD, LPUSH 等)追加到 AOF 文件的末尾。当 Redis 服务器重启时,会重新执行 AOF 文件中的命令来恢复数据。
实现原理:
- 命令追加 (Append): 当 Redis 执行完一个写命令后,会将该命令以 Redis 协议格式追加到 AOF 文件的末尾。
- 文件同步 (Sync): 为了保证数据安全,需要将 AOF 文件内容同步到磁盘。Redis 提供了三种同步策略,通过 appendfsync 配置项控制:always: 每次写命令执行完后,立即将 AOF 缓冲区的内容同步到磁盘。数据安全性最高,但性能最低。everysec: 每秒钟将 AOF 缓冲区的内容同步到磁盘。数据安全性和性能的折中方案,也是默认推荐的配置。 如果系统宕机,最多丢失 1 秒的数据。no: 不主动同步,由操作系统决定何时同步到磁盘。性能最高,但数据安全性最低。 可能丢失较多数据。
AOF 重写 (Rewrite):
随着时间的推移,AOF 文件会越来越大,因为它记录了所有的写命令,包括很多冗余的命令 (例如,对同一个 key 多次修改,AOF 文件中会记录多次 SET 命令)。为了减小 AOF 文件的大小,Redis 提供了 AOF 重写机制。
AOF 重写原理:
AOF 重写不是对旧的 AOF 文件进行任何读取和分析,而是读取 Redis 服务器当前内存中的数据,然后将这些数据转换成一系列 Redis 命令,并将这些命令写入到一个新的 AOF 文件中。新的 AOF 文件只包含重建当前数据集所需的最少命令。
AOF 重写过程:
AOF 重写可以通过 BGREWRITEAOF 命令手动触发,也可以通过 Redis 的配置自动触发:
- 手动触发: BGREWRITEAOF 命令:异步执行 AOF 重写,Redis 会 fork 一个子进程来执行重写操作,主进程仍然可以继续处理客户端请求。
- 自动触发: 通过在 redis.conf 配置文件中设置 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 指令,可以配置 Redis 在满足一定条件时自动执行 BGREWRITEAOF 命令。例如:
- 复制代码
- auto-aof-rewrite-percentage 100 # 当 AOF 文件大小比上次重写后的大小增长了 100% 时触发重写 auto-aof-rewrite-min-size 64mb # 只有当 AOF 文件大小大于 64MB 时才触发重写
BGREWRITEAOF 命令的详细执行过程 (类似于 BGSAVE):
- 客户端发送 BGREWRITEAOF 命令或满足自动触发条件时,Redis 主进程接收到请求。
- Redis 主进程调用 fork() 系统调用创建出一个子进程。
- 子进程负责读取 Redis 内存中的数据,并将数据转换成一系列 Redis 命令,写入到一个临时的 AOF 重写文件中。 同样使用了写时复制技术。
- 在重写过程中,主进程仍然可以处理客户端请求。为了保证数据一致性,Redis 会维护一个 AOF 重写缓冲区,记录在重写期间主进程执行的新写命令。
- 当子进程完成 AOF 重写后,会将 AOF 重写缓冲区中的命令追加到新的 AOF 重写文件的末尾,保证数据完整性。
- 子进程将新的 AOF 重写文件替换旧的 AOF 文件。
- 子进程退出,主进程继续处理客户端请求。
AOF 文件的结构:
AOF 文件是文本文件,内容是 Redis 命令序列,使用 Redis 协议格式存储。例如:
复制代码*3
\$3
SET
\$3
key
\$5
value
*3
\$6
SADD
\$4
myset
\$5
item1
AOF 的优点:
- 数据安全性更高: 根据 appendfsync 的配置,AOF 可以提供更高的数据安全性,特别是 always 策略,几乎不会丢失数据。
- 可读性: AOF 文件是文本文件,可读性较好,可以查看和分析 AOF 文件中的命令。
- 易于修复: 如果 AOF 文件损坏,可以手动编辑 AOF 文件,删除错误的命令,然后重启 Redis 恢复数据。
AOF 的缺点:
- 文件体积较大: AOF 文件记录了所有写命令,通常比 RDB 文件大。
- 恢复速度较慢: 恢复数据时需要重新执行 AOF 文件中的所有命令,恢复速度比 RDB 慢。
- 性能略有影响: always 策略对性能有一定影响,everysec 策略性能影响相对较小。
RDB 和 AOF 的选择和使用建议:
- 数据安全性要求高: 建议使用 AOF 持久化,并配置 appendfsync everysec 或 always 策略。
- 数据安全性要求不高,但需要快速恢复: 可以使用 RDB 持久化。
- 同时使用 RDB 和 AOF: Redis 官方推荐同时开启 RDB 和 AOF 持久化。在这种情况下,Redis 重启时会优先使用 AOF 文件恢复数据,因为 AOF 文件通常数据更完整。
- 只使用 RDB: 如果你可以容忍一定的数据丢失,并且需要快速恢复,可以只使用 RDB 持久化。
- 只使用 AOF: 如果你对数据安全性要求非常高,并且可以接受恢复速度较慢,可以使用 AOF 持久化。
- 禁用持久化: 如果你只是将 Redis 作为缓存使用,并且不关心数据丢失,可以禁用持久化。
总结:
RDB 和 AOF 是 Redis 提供的两种主要的持久化方式,各有优缺点。选择哪种持久化方式取决于你的应用场景和对数据安全性、性能、恢复速度等方面的需求。通常建议同时开启 RDB 和 AOF,以获得更好的数据安全性和恢复速度。
相关推荐
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
-
在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...
- 第四节 Windows 系统 Docker 安装全指南
-
一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...
- C++ std:shared_ptr自定义allocator引入内存池
-
当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...
- Activiti 8.0.0 发布,业务流程管理与工作流系统
-
Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
-
MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...
- Springboot数据访问(整合Mybatis Plus)
-
Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
-
见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...
- Mybatis入门看这一篇就够了(mybatis快速入门)
-
什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...
- Springboot数据访问(整合druid数据源)
-
Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
-
什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...
- 企业数据库安全管理规范(企业数据库安全管理规范最新版)
-
1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...
- Oracle 伪列!这些隐藏用法你都知道吗?
-
在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...
- Oracle 高效处理数据的隐藏神器:临时表妙用
-
各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...
- Oracle 数据库查询:多表查询(oracle多表关联查询)
-
一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...
- 一文掌握怎么利用Shell+Python实现多数据源的异地备份程序
-
简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
- 第四节 Windows 系统 Docker 安装全指南
- C++ std:shared_ptr自定义allocator引入内存池
- Activiti 8.0.0 发布,业务流程管理与工作流系统
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
- Springboot数据访问(整合Mybatis Plus)
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
- Mybatis入门看这一篇就够了(mybatis快速入门)
- Springboot数据访问(整合druid数据源)
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)