Redis 持久化机制浅析

1. 持久化机制的作用

Redis 是基于内存的数据结构数据库,虽然读写性能非常高,但所有数据默认保存在内存中。一旦服务器宕机、进程意外崩溃或容器重启,内存中的数据将全部丢失。这对于生产环境的可用性与可靠性是极其危险的。因此,Redis 提供了持久化机制,将内存数据定期或实时写入磁盘,以便在服务重启时能够从磁盘数据中恢复,防止宕机导致的数据全部丢失。

2. 三种持久化机制

Redis 提供了三种持久化方式:

  1. RDB(Redis DataBase)快照持久化
  2. AOF(Append Only File)日志持久化
  3. 混合持久化(RDB + AOF,Redis 4.0+ 引入)

在生产环境中使用时,这些策略都可能会失败。

2.1 RDB 快照持久化

1 基本原理

RDB 是一种 周期性快照机制,Redis 会在满足特定条件时,将当前内存中的所有数据以快照方式保存为一个二进制文件(默认为 dump.rdb

RDB 采用了 COW(Copy-On-Write)机制,由 Redis 主进程通过 fork() 创建子进程,子进程将内存快照写入磁盘,而主进程则继续处理客户端请求,保证高并发。

子进程刚创建时共享父进程内存,但当父进程修改某块内存数据时,会将该页面复制一份,以避免子进程快照不一致,这一机制称为 “页面分离”。

2 触发方式
  • 自动触发:通过配置 redis.conf 文件中的 save 参数,如:
 //默认如下配置:
save 900 1:每隔900s(15min),如果有超过1个key发生了变化,就写一份新的RDB文件
save 300 10:每隔300s(5min),如果有超过10个key发生了变化,就写一份新的RDB文件
save 60 10000:每隔60s(1min),如果有超过10000个key发生了变化,就写一份新的RDB文件
//(配置多种策略可以同时生效,无论满足哪一种条件都会写一份新的RDB文件)
  • 手动触发
    • save:阻塞主进程,生成 RDB 文件。
    • bgsave:异步触发,fork 子进程处理持久化。
3 优缺点

优点:对主进程性能影响小,快照文件便于备份与远程传输。恢复速度快,适合冷启动。数据文件紧凑,占用空间小。

缺点:数据可能丢失几分钟。 fork 子进程时内存翻倍,数据量大时存在性能抖动风险。使用特定二进制格式存储,版本兼容性差。

4 RDB可能的故障场景

​​场景1:数据丢失​​。默认配置下,如果Redis在快照之间崩溃,可能丢失最多15分钟数据。

​​场景2:Fork失败​​。当内存不足时,fork操作可能失败。

# Redis log
[1111]  4 Aug # Can't save in background: fork: Cannot allocate memory

​​场景3:磁盘空间耗尽​​。RDB文件先写入临时位置,再原子性的重命名。如果写入期间磁盘空间不足,快照会失败,Redis仍然继续运行。

# Redis log
[1111]  4 Aug # Write error saving DB on disk: No space left on device

​​场景4:断电后RDB文件损坏​​。断电时RDB文件只写入部分内容。重启时Redis拒绝启动损坏的RDB文件。

# Redis startup log
[1111]  4 Aug # Short read or OOM loading DB. Unrecoverable error, aborting now.

2.2 AOF 日志持久化

1 基本原理

AOF 通过将所有修改命令(如 SETDEL按顺序追加到日志文件(默认为 appendonly.aof)中来实现持久化。Redis 在收到命令后,先记录日志,再执行命令。写入流程如下:

  • 指令被追加至 OS 缓冲区;
  • 根据 appendfsync 策略定期 fsync 到磁盘。
2 配置方式

通过 appendfsync 参数配置:

appendfsync everysec   # 每秒刷一次
appendfsync always     # 每写入一条命令都 fsync,最安全但最慢
appendfsync no         # 不主动 fsync,完全交由 OS 决定
3 重写(Rewrite)

随着操作积累,AOF 文件会越来越大,影响重启速度。因此 Redis 提供了AOF Rewrite

  • fork 子进程;
  • 将当前内存快照转化为最小指令集;
  • 合并重写后的小文件;
  • 替换原有 AOF 文件。
// 自动触发规
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
4 优缺点

优点:更高的数据安全性,最多丢失 1 秒数据。日志可读,可手动恢复误删数据。重写机制可控制文件大小。
缺点:恢复速度比 RDB 慢。写入性能略低于 RDB。文件体积通常比 RDB 大。

5 AOF可能的失败场景

​​场景1:系统崩溃后AOF损坏​​

# Redis startup log
[1111]  4 Aug # Bad file format reading the append only file: 
make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

​​场景2:AOF重写失败​​。随着AOF文件增长,Redis会定期重写以保持精简。但这个重写过程可能出错。

# Redis log during rewrite failure
[1111]  4 Aug # Error rewriting AOF: No space left on device
[1111]  4 Aug # AOF rewrite failed: 
Previous AOF was kept, but disk is full, cannot proceed with rewrite.

这个错误的大意是重写AOF错误,因为设备剩余存储空间不足。虽然重写失败,但Redis继续向旧AOF文件追加。磁盘完全填满后,Redis开始拒绝写入。

​​场景3:重写期间内存爆炸​​。AOF重写期间,Redis在内存中缓冲所有新写入。如果重写耗时过长(慢磁盘常见),可能在"安全"的重写操作期间因OOM而崩溃。

​​场景4:"appendfsync always"导致脑裂​​。假设对Redis中的重要数据使用appendfsync always策略。如果这个Redis实例因为网络问题等性能变差,会被负载均衡器将其标记为不健康,把流量转向备份实例。网络恢复后,会得到两个包含不同数据的Redis实例。

2.3 混合持久化(RDB + AOF)

Redis 4.0 引入混合持久化模式:在重写 AOF 文件时,先写入 RDB 快照,再追加从快照开始到当前的 AOF 增量日志,融合了二者优点。
配置参数:

aof-use-rdb-preamble yes

注意:混合持久化的 AOF 文件前段为 RDB 格式,老版本 Redis 不兼容。

优点:

  • 恢复效率高,RDB 快照 + 小量 AOF 日志。
  • 兼具 AOF 的数据完整性与 RDB 的恢复速度。

缺点:

  • 文件结构复杂,可读性差。
  • 4.0 以下版本不支持。

3. 持久化监控信息

Redis的INFO命令能显示持久化状态,但信息并不完整。

# INFO显示内容
rdb_last_save_time:1678889001
rdb_last_bgsave_status:ok
aof_enabled:1
aof_last_rewrite_time_sec:45# 未显示内容
# - Fork失败率
# - 磁盘空间趋势
# - 损坏检测
# - 性能影响

以下是一个设置额外的监控数据的示例。

#!/bin/bash
# 检查RDB保存失败
redis-cli LASTSAVE | awk '{last_save = $1;now = systime();diff = now - last_save;if (diff > 3600) {  # 1小时未保存则告警print "警告:RDB已" diff "秒未保存";}
}'# 检查AOF健康状态
redis-cli INFO persistence | grep aof_last_write_status | grep -v ok && echo "AOF写入失败"# 监控持久化磁盘空间
df -h /var/lib/redis | awk 'NR==2 {if (int($5) > 80) {print "警告:Redis磁盘使用" $5 "已满";}
}'

4. 恢复策略

1. AOF损坏恢复参考示例

# 步骤1:备份损坏文件
cp appendonly.aof appendonly.aof.corrupted# 步骤2:尝试自动修复
redis-check-aof --fix appendonly.aof# 步骤3:检查丢失内容
redis-check-aof appendonly.aof.corrupted > corruption_report.txt# 步骤4:自动修复失败时人工干预
# 编辑AOF文件,移除末尾不完整命令
tail -20 appendonly.aof.corrupted  # 查找不完整命令
head -n -5 appendonly.aof.corrupted > appendonly.aof  # 移除最后5行

2 RDB损坏恢复参考示例

# 步骤1:检查RDB是否可修复
redis-check-rdb dump.rdb# 步骤2:不可修复则从备份恢复
aws s3 cp s3://backup-bucket/redis/dump.rdb.gz .
gunzip dump.rdb.gz# 步骤3:无备份则重建并重载应用数据

5. 完整配置参考

1 Redis配置

# redis.conf - 生产环境配置# RDB配置
# 更频繁保存,多条件触发
save 900 1      # 15分钟内任何变更
save 300 10     # 5分钟内10+变更
save 60 100     # 1分钟内100+变更# RDB失败时停止接受写入
stop-writes-on-bgsave-error yes# 压缩RDB文件
rdbcompression yes# AOF配置  
appendonly yes
appendfilename "appendonly.aof"# 每秒同步(良好的持久性/性能平衡)
appendfsync everysec# 启用AOF重写控制文件大小
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb# AOF损坏但可读时不丢失数据
aof-load-truncated yes# 使用RDB-AOF混合加速重启
aof-use-rdb-preamble yes# 内存管理
maxmemory 6gb  # 为fork期间的COW预留空间
maxmemory-policy allkeys-lru# 禁用内存过量使用
vm-enabled no

2 自动备份配置

#!/bin/bash
# redis-backup.sh - 每小时执行DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/redis"
S3_BUCKET="company-redis-backups"# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE# 触发RDB保存
redis-cli BGSAVE
sleep 30  # 等待保存完成# 复制文件
cp /var/lib/redis/dump.rdb $BACKUP_DIR/$DATE/
cp /var/lib/redis/appendonly.aof $BACKUP_DIR/$DATE/# 压缩上传
tar -czf $BACKUP_DIR/$DATE.tar.gz $BACKUP_DIR/$DATE/
aws s3 cp $BACKUP_DIR/$DATE.tar.gz s3://$S3_BUCKET/# 清理旧备份(本地保留48小时,S3保留30天)
find $BACKUP_DIR -name "*.tar.gz" -mtime +2 -delete
aws s3 ls s3://$S3_BUCKET/ | awk '$1 < "'$(date -d '30 days ago' '+%Y-%m-%d')'" {print $4}' | xargs -I {} aws s3 rm s3://$S3_BUCKET/{}

6. 常用持久化相关命令

命令说明
save阻塞生成 RDB 快照
bgsave后台生成 RDB 快照
bgrewriteaof重写 AOF 文件
info Persistence查看持久化信息
redis-check-aof检查 / 修复 AOF 文件
redis-check-rdb检查 RDB 文件
shutdown安全关闭,自动保存 RDB
kill -9强制关闭,可能导致数据丢失

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

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

相关文章

使用MatterJs物理2D引擎实现重力和鼠标交互等功能,有点击事件(盒子堆叠效果)

使用MatterJs物理2D引擎实现重力和鼠标交互等功能&#xff0c;有点击事件&#xff08;盒子堆叠效果&#xff09; 效果图&#xff1a;直接上代码&#xff0c;我是用的是html&#xff0c;使用了MatterJs的cdn&#xff0c;直接复制到html文件中然后在浏览器打开即可 <!DOCTYPE …

如何玩转 Kubernetes K8S

在容器化时代&#xff0c;虽然Docker已经很强大了&#xff0c;但是在实际使用上还是有诸多不便&#xff0c;比如集群管理、资源调度、文件管理等等。 不过目前也涌现了很多解决方案&#xff0c;比如 Mesos、Swarm、Kubernetes 等等&#xff0c;其中谷歌开源的 Kubernetes就是其…

论文阅读笔记:Dataset Condensation with Gradient Matching

论文阅读笔记&#xff1a;Dataset Condensation with Gradient Matching1. 解决了什么问题&#xff1f;(Motivation)2. 关键方法与创新点 (Key Method & Innovation)2.1 核心思路的演进&#xff1a;从参数匹配到梯度匹配2.2 算法实现细节 (Implementation Details)3. 实验结…

网安学习no.22

一、基础系统信息命令&#xff08;简单入门&#xff09;uname作用&#xff1a;查看系统内核信息示例&#xff1a;uname -a&#xff08;显示完整内核版本、主机名、硬件架构等&#xff09;hostname作用&#xff1a;查看或设置主机名示例&#xff1a;hostname&#xff08;显示当前…

AJAX的引入

是的&#xff0c;AJAX 的一个主要特点就是通过 局部刷新 来实现与服务器的交互&#xff0c;而不需要重新加载整个页面。通过 AJAX&#xff0c;JavaScript 可以发送异步的 HTTP 请求&#xff0c;接收到响应数据后&#xff0c;更新页面的某个部分&#xff08;DOM&#xff09;。这…

SpringBoot 整合 Langchain4j AIService 深度使用详解

目录 一、前言 二、AIService 介绍 2.1 AiService 是什么 2.2 AiService 主要功能 2.3 AiService 使用步骤 三、AIService 操作实践 3.1 前置准备 3.1.1 获取apikey 3.1.2 导入核心依赖 3.1.3 添加配置文件 3.1.4 前置导入案例 3.2 AIService 案例操作详解 3.2.1 入…

基于FFmpeg和HLS的大文件分片传输方案

1&#xff1a;功能介绍 在视频这类大文件的传输过程中&#xff0c;经常会因为文件太大而受到网络带宽的限制。比如在实现视频预览功能时&#xff0c;常常会出现长时间加载、缓存卡顿的问题。我在项目中也遇到了类似的情况&#xff0c;于是采用了这个解决方案。 我们可以利用 FF…

体育场预定-下单-扣减库存一致性

流程1:通过库存服务缓存(缓存里面不仅有位图存储该时间点id的位置信息还有库存信息)的Redis获取令牌2:拿着令牌向订单服务同步下单如果有令牌就执行下面的Redis&#xff0c;如果没有就直接返回扣减Redis库存缓存扣减成功:继续扣减失败:返回前端重试整套流程3:1锁2查3更新生成订…

【计算机网络】王道考研笔记整理(3)数据链路层

目录 第三章 数据链路层 3.1 数据链路层的功能 3.2 组帧 3.2.1 字符计数法 3.2.2 字节填充法 3.2.3 零比特填充法 3.2.4 违规编码法 3.3 差错控制 3.3.1 奇偶校验码 3.3.2 CRC 校验码 3.3.3 海明校验码 3.4 可靠传输与流量控制 3.4.1 滑动窗口机制 3.4.2 停止 - 等待…

【后端】java 抽象类和接口的介绍和区别

文章目录一、抽象类&#xff08;Abstract Class&#xff09;二、接口&#xff08;Interface&#xff09;三、核心区别总结四、使用场景对比五、从设计思想理解最佳实践在Java中&#xff0c;抽象类&#xff08;Abstract Class&#xff09;和接口&#xff08;Interface&#xff0…

Apache OFBiz Scrum 组件命令注入漏洞

【严重】Apache OFBiz Scrum 组件命令注入漏洞 漏洞描述 Apache OFBiz 是一款知名的开源企业资源规划(ERP)解决方案&#xff0c;它提供了一整套开箱即用的企业级应用。Scrum 是 OFBiz 的一个插件&#xff0c;旨在为敏捷开发团队提供项目管理功能&#xff0c;其中包括与 SVN 版…

FastAPI入门:多个文件、后台任务、元数据和文档 URL

更大的应用 - 多个文件 假设文件结构如下&#xff1a;. ├── app # 「app」是一个 Python 包 │ ├── __init__.py # 这个文件使「app」成为一个 Python 包 │ ├── main.py # 「main」模块&#xff0c;例如 import app.main │ ├…

一个示例mcp agent功能的交互式框架

https://github.com/whym3/Deepseek_MCPDeepseek_MCP https://github.com/whym3/Deepseek_MCP Deepseek_MCP是一个演示mcp agent的框架&#xff0c;基于Flask开发&#xff0c;支持在浏览器采用交互方式与deepseek及agent对话。需要注册外部Deepseek api&#xff0c;不支持本地…

nodejs 基础知识-2

模块的暴露和导入 编写date.js module.exports.echo 导出的名称 module.exports.echo function echo(){ return Date.now(); } 编写 index.js const echoDate require(‘./date.js’) 在index引入 console.log(echoDate.echo()); //调用 开发一个自定义模块 exports.forma…

递归推理树(RR-Tree)系统:构建认知推理的骨架结构

探索基于三维评估的动态推理系统如何实现智能决策与知识演化引言 在复杂问题求解领域&#xff08;如战略决策或科学探索&#xff09;&#xff0c;人类思维的递归本质为AI系统设计提供了重要启发。我设计并实现的递归推理树&#xff08;Recursive Reasoning Tree, RR-Tree&#…

《动手学深度学习》读书笔记—9.5机器翻译与数据集

本文记录了自己在阅读《动手学深度学习》时的一些思考&#xff0c;仅用来作为作者本人的学习笔记&#xff0c;不存在商业用途。 语言模型是自然语言处理的关键&#xff0c; 而机器翻译是语言模型最成功的基准测试。 因为机器翻译正是将输入序列转换成输出序列的 序列转换模型&a…

Mysql进行操作时锁的具体行为

场景一&#xff1a;单个事务更新一条存在的数据 假设有表 user (id PK, name, age)&#xff0c;数据&#xff1a;[id1, nameAlice, age25] 你的 SQL&#xff1a; UPDATE user SET age 26 WHERE id 1; 底层动作&#xff1a; 事务 A (主动方) 发起更新请求。Lock Manager 介入&…

人工智能领域、图欧科技、IMYAI智能助手2025年7月更新月报

IMYAI 平台 2025 年 7 月重要功能更新与优化汇总 2025年07月31日更新 细节优化&#xff1a; 修复了移动端提交后自动弹出侧边栏的BUG。优化对话高级配置界面&#xff0c;增加滚动条并固定高度&#xff0c;避免内容超出屏幕。音乐生成界面的人声选择新增“合唱”选项&#xff…

HTTP 与 HTTPS 的区别深度解析:从原理到实践

HTTP 和 HTTPS 是现代 Web 开发中不可或缺的协议&#xff0c;它们决定了浏览器与服务器之间数据传输的方式。HTTPS 作为 HTTP 的安全版本&#xff0c;在安全性、性能和用户体验上都有显著提升。本文将通过万字篇幅&#xff0c;结合图表和代码示例&#xff0c;详细剖析 HTTP 与 …

STM32F407VET6学习笔记11:smallmodbus_(多从机)创建新的slave从机

今日记录一些smallmodbus 创建新的slave 从机 的过程&#xff0c;以及使用的关键点. 目录 创建新的从机对应操作函数与buffer 创建新的从机线程与操作代码&#xff1a; slave使用的要点&#xff1a; 完整的slave代码&#xff1a; 能正常通信&#xff1a; 创建新的从机对应操作函…