【🔥🔥🔥RDB还是AOF ?】Redis持久化原理全景解读与生产级决策手册
Redis 的持久化机制是其高可用性的基石,主要包含 RDB (Redis Database) 和 AOF (Append Only File) 两种方式,它们的设计目标、实现原理和适用场景各有不同。
一、RDB (Redis Database) - 快照
原理:
- RDB 在指定的时间间隔内,将内存中整个 Redis 数据集生成一个时间点快照 (Point-in-Time Snapshot)。
- 生成快照的过程:
- Redis 主进程
fork出一个子进程。 - 子进程将内存中的数据序列化写入一个临时的 RDB 文件。
- 在子进程完成写入后,用这个新的 RDB 文件替换旧的 RDB 文件(
rename操作是原子的)。
- Redis 主进程
- RDB 文件是一个二进制压缩文件,结构紧凑。
触发方式:
- 手动触发:
SAVE: 阻塞 Redis 主进程,直到 RDB 文件创建完毕。生产环境几乎不用,会导致服务长时间不可用。BGSAVE: 后台异步进行快照生成。Redis 会fork子进程来完成工作,主进程继续提供服务。推荐使用。
- 自动触发:
- 根据配置文件
redis.conf中的save <seconds> <changes>规则触发BGSAVE。例如:save 900 1: 900秒(15分钟)内有至少1个key发生变化。save 300 10: 300秒(5分钟)内有至少10个key发生变化。save 60 10000: 60秒内有至少10000个key发生变化。
- 执行
SHUTDOWN命令关闭服务器时(如果未配置 AOF 或 AOF 未开启)。 - 主从复制时,主节点收到
SYNC命令开始全量复制时会自动触发BGSAVE生成 RDB 发送给从节点。
- 根据配置文件
- 手动触发:
优点:
- 性能高,恢复速度快: RDB 文件是紧凑的二进制文件,生成和加载(启动恢复)都非常快,非常适合大规模数据恢复和灾难恢复。
- 磁盘空间占用小: 二进制压缩格式显著减小了磁盘占用。
- 最大化 Redis 性能:
BGSAVE由子进程完成,主进程只承担fork的短暂开销,对读写服务影响较小。 - 适合备份: 单个文件方便备份和传输到远程数据中心或云存储。
缺点:
- 数据丢失风险高: 两次快照之间的数据修改会丢失。如果配置为每5分钟保存一次,服务器故障可能丢失最多5分钟的数据。对数据安全性要求高的场景不合适。
fork可能阻塞服务: 如果数据集非常大(例如几十GB),fork操作本身可能比较耗时(尤其是在虚拟机上),导致主进程短暂停顿(毫秒到秒级),影响服务响应时间。- 版本兼容性: 老版本 Redis 生成的 RDB 文件可能无法在新版本 Redis 上恢复。
二、AOF (Append Only File) - 日志追加
原理:
- AOF 记录 Redis 服务器收到的每一条写命令(及其参数)。
- 这些命令以 Redis 协议格式追加写入到 AOF 文件的末尾。
- Redis 重启时,通过重新执行 AOF 文件中的所有写命令来重建内存数据集状态。
- AOF 重写: 为了解决 AOF 文件不断膨胀的问题,Redis 会定期根据内存中的当前数据状态,创建一个新的、更小的 AOF 文件来替换旧的。重写过程由子进程完成(类似
BGSAVE),期间新的写命令会同时记录到内存缓冲区和旧的 AOF 文件中。重写完成后,缓冲区内容追加到新 AOF 文件,然后原子替换旧文件。
触发方式与配置:
- 开启 AOF: 在
redis.conf中设置appendonly yes。 - 写入策略 (appendfsync): 控制何时将 AOF 缓冲区的内容同步到磁盘,这是影响性能和数据安全性的关键配置。
no: 由操作系统决定何时同步。性能最好,但数据丢失风险最高(操作系统缓存未写入磁盘的数据在宕机时会丢失)。always: 每个写命令都同步到磁盘。数据最安全(最多丢失一个命令),但性能最差(磁盘 I/O 成为瓶颈)。everysec(默认): 每秒同步一次。在性能和数据安全性之间取得良好平衡。理论上最多丢失1秒的数据。这是最常用的配置。
- AOF 重写触发:
- 手动触发:执行
BGREWRITEAOF命令。 - 自动触发:根据
redis.conf中的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置。例如:auto-aof-rewrite-percentage 100(当前 AOF 文件大小比上次重写后的大小增长了100%)auto-aof-rewrite-min-size 64mb(且当前 AOF 文件大小至少达到 64MB)
- 手动触发:执行
- 开启 AOF: 在
优点:
- 数据安全性高: 默认的
everysec策略最多丢失1秒数据,always策略理论上不丢失数据(但性能极低)。非常适合对数据完整性要求高的场景。 - 可读性(一定程度上): AOF 文件是文本格式(Redis 协议),便于人工理解和修复(虽然通常不直接编辑)。
- 容灾性强: 即使文件末尾因故障写入不完整,Redis 自带工具
redis-check-aof可以轻松修复(删除不完整的命令)。 - 后台重写:
BGREWRITEAOF由子进程执行,不影响主进程服务。
- 数据安全性高: 默认的
缺点:
- 文件体积大: 相比同数据集的 RDB 文件,AOF 文件通常更大(即使经过重写)。
- 恢复速度慢: 重新执行所有命令来恢复数据,比加载 RDB 文件慢得多,尤其当 AOF 文件很大时。
- 性能略低于 RDB: 即使使用
everysec,AOF 的写入吞吐量通常也低于 RDB(尤其是在大量写入场景下)。always策略性能影响显著。 - 历史 Bug: AOF 重写逻辑在极端情况下(如断电)曾出现过一些边界 Bug(虽然现在已比较成熟)。
三、如何选择 RDB 和 AOF?
没有绝对的最佳答案,选择取决于你的应用对数据安全性和性能的要求:
追求最高性能,能容忍分钟级数据丢失:
- 仅使用 RDB。 这是最简单的配置,适合缓存、会话存储等对丢失少量数据不敏感的场景。配置好
save规则即可。
- 仅使用 RDB。 这是最简单的配置,适合缓存、会话存储等对丢失少量数据不敏感的场景。配置好
追求高数据安全性,能接受一定的性能损失和较慢的恢复速度:
- 仅使用 AOF (appendfsync everysec)。 这是最常见的生产环境配置,在性能和安全性之间取得了很好的平衡。适用于需要持久化订单、交易、用户状态等关键数据的场景。强烈建议启用 AOF。
需要非常高的数据安全性,能容忍显著性能下降:
- 仅使用 AOF (appendfsync always)。 牺牲性能换取最高的数据安全性(理论上零丢失)。仅在极端要求数据一致性的场景使用(如金融核心交易),通常需要配合高性能 SSD 磁盘。
希望平衡性能和数据安全性,并需要快速恢复能力:
- 同时启用 RDB 和 AOF (推荐方式)。
- 数据安全: 依赖 AOF (
appendfsync everysec)。 - 快速恢复: 依赖 RDB。可以定期(如每天)手动执行
BGSAVE备份 RDB,或者在配置中保留合理的save规则(但频率可以设低一些,如save 3600 1每小时保存一次)。 - 重启恢复流程: Redis 重启时优先使用 AOF 文件来恢复数据(因为它通常包含更完整的数据集状态)。只有当 AOF 功能关闭时,才会使用 RDB 文件恢复。
- 数据安全: 依赖 AOF (
- Redis 4.0+ 的混合持久化:
- 在
redis.conf中设置aof-use-rdb-preamble yes。 - AOF 重写时,子进程将内存数据以 RDB 格式写入新的 AOF 文件的开头部分(
preamble),然后将重写期间缓冲的增量写命令以 AOF 格式追加到文件后面。 - 优点: 结合了 RDB 的快速加载(加载开头 RDB 部分)和 AOF 的数据完整性(加载后续增量命令)。生成的混合文件通常比纯 AOF 文件小,加载速度比纯 AOF 快很多。这是目前非常推荐的生产环境配置方式。
- 在
- 同时启用 RDB 和 AOF (推荐方式)。
总结与建议
- 理解风险: 评估应用能容忍多少数据丢失(RPO - Recovery Point Objective)。
- 基准测试: 在你的硬件和工作负载下测试不同配置的性能(吞吐量、延迟)。
- 生产推荐:
- 首选方案: 同时启用 RDB 和 AOF (
appendfsync everysec),并开启混合持久化 (aof-use-rdb-preamble yes)。这提供了最佳的数据安全性和较好的恢复速度。 - 纯 AOF (
appendfsync everysec) 也是一个非常稳健的选择。 - 尽量避免仅使用 RDB,除非数据完全不重要。
- 首选方案: 同时启用 RDB 和 AOF (
- 监控与运维:
- 监控磁盘空间(AOF 文件可能很大)。
- 监控
fork耗时(info stats中的latest_fork_usec)。 - 定期备份 RDB/AOF 文件到异地。
- 根据数据增长情况调整 AOF 重写触发条件 (
auto-aof-rewrite-*)。 - 预留足够的磁盘 I/O 能力给 AOF。
最终选择应基于你的具体业务需求、数据重要性、性能预算和运维能力进行权衡。在 Redis 4.0+ 环境下,开启混合持久化通常是满足大多数生产环境需求的最佳实践。
【🔥🔥🔥RDB还是AOF ?】Redis持久化原理全景解读与生产级决策手册的更多相关文章
- 【Java面试】RDB 和 AOF 的实现原理、优缺点
Hi,大家好,我是Mic. 一个工作了5年的粉丝私信我,最近面试碰到很多Redis相关的问题. 其中一个面试官问他Redis里面的持久化机制,没有回答得很好. 希望我帮他系统回答一下. 关于Redis ...
- redis 实战操作RDB和AOF快照持久化
前言:redis是我们常用的缓存方式,今天就来介绍下两种持久化的方式吧,先科普概念,再实战操作 一.RDB Redis将某一时刻的快照(备份的数据库数据)保存成一种称为RDB格式的文件中,这种格式是经 ...
- 两种Redis持久化原理的详解
Redis为持久化提供了两种方式: RDB:在指定的时间间隔能对你的数据进行快照存储. AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据. 本文将通过下面内容的介 ...
- redis的 rdb 和 aof 持久化的区别
aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...
- Redis 持久化之RDB和AOF
Redis 持久化之RDB和AOF Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File).如果你想快速了解和使用RDB和AOF,可以直 ...
- redis两种持久化方式RDB和AOF
目录 前言 1. Redis 数据库结构 2. RDB 持久化 2.1. RDB 的创建和载入 2.1.1. 手动触发保存 SAVE 命令 BGSAVE 命令 SAVE 和 BGSAVE 的比较 2. ...
- Redis持久化存储——>RDB & AOF
Redis中两种持久化存储机制RDB和AOF redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB ...
- redis 持久化 AOF和 RDB 引起的生产故障
概要 最近听开发的同事说,应用程序连接 redis 时总是抛出连接失败或超时之类的错误.通过观察在 redis 日志,发现日志中出现 "Asynchronous AOF fsyn ...
- 配置方案:Redis持久化RDB和AOF
Redis持久化方案 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘.当下次Redis重启时,利 ...
- Linux - redis持久化RDB与AOF
目录 Linux - redis持久化RDB与AOF RDB持久化 redis持久化之AOF redis不重启,切换RDB备份到AOF备份 确保redis版本在2.2以上 实验环境准备 备份这个rdb ...
随机推荐
- 【渗透 Tips】解决Edge的IE模式下无法抓包情况
问题说明 在日常渗透中往往避免不了站点的环境适配问题,有一些站点只能使用IE模式访问,此时便会想着可能使用内置proxy插件代理至抓包软件即可,事实上这并不能很好解决. 如上图所示,即使挂上了yaki ...
- 代码随想录第三天 | Leecode 203. 移除链表元素、707. 设计链表、206. 翻转链表
Leecode 203 移除链表元素 题目链接:https://leetcode.cn/problems/remove-linked-list-elements/ 题目描述 给你一个链表的头节点 he ...
- Docker不装C盘
Docker默认安装在C盘,这未来随着docker使用必定会导致C盘空间吃紧.所以本文提前进行空间布局,将docker默认安装路径软链接到D盘.软链接D盘Docker默认安装路径为C:\Program ...
- ShadowSql之表达式树
ShadowSql的主要思想通过表和字段的影子来拼写sql .net中的表达式树是作为模型类的影子,非常契合ShadowSql 拿表达式树来拼写sql就和EF类似 一.nuget包 nuget安装Sh ...
- java等比压缩图片工具类
工具类 package com.chinaums.abp.util; import javax.imageio.ImageIO; import java.awt.*; import java.awt. ...
- 【2020.11.24提高组模拟】变换 (transform) 题解
[2020.11.24提高组模拟]变换 (transform) 题解 题意描述 给一个大小为\(n\)的\(01\)环\(A\),点编号为\(0,1,\dots,n-1\).每一个点\(i\)都与\( ...
- php链式调用
我们经常在项目中会写到 Mode::find()->where()->orderBy()->limit(); 链式调用,那么它是怎么实现的呢? 昨天看韩天峰大佬的视频,学到了 关键点 ...
- 商品中心—8.商品C端处理高并发的技术文档
大纲 1.商品C端的高并发架构 2.商品C端的布隆过滤器组件 3.Guava缓存的封装与使用 4.商品C端的接口设计与运行流程总结 5.商品C端系统对商品数据新增和变更时的处理 1.商品C端的高并发架 ...
- DBA备库工具:Oracle环境中表空间全自动扩容
我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效 ...
- YOLOv5报错:AttributeError: ‘Upsample‘ object has no attribute ‘recompute_scale_factor‘ 的解决方案
YOLOv5报错:AttributeError: 'Upsample' object has no attribute 'recompute_scale_factor' 的解决方案 错误代码: Fil ...