Redis的持久化

Redis 主要提供两种持久化方案:RDB(Redis Database)AOF(Append-Only File)。它们各有特点,可以单独使用,也可以同时启用(默认情况下两者都开启,但通常需要根据场景配置)。


1. RDB(快照持久化)

RDB 通过生成某个时间点的数据快照来持久化数据,默认保存为 dump.rdb 文件。

工作原理:

  • 根据配置规则,在满足条件时自动触发快照(如"N 秒内至少 M 个键被修改")。

  • 也可以手动执行 SAVE(阻塞)或 BGSAVE(后台子进程执行)命令。

  • 快照生成时,父进程继续处理请求,子进程将数据写入临时 RDB 文件,完成后替换旧文件。

配置示例(redis.conf):

bash 复制代码
save 900 1      # 900秒内至少1个键被修改则触发
save 300 10     # 300秒内至少10个键被修改
save 60 10000   # 60秒内至少10000个键被修改

dir ./          # 保存路径
dbfilename dump.rdb

优点:

  • 性能好:生成快照时通过子进程处理,主进程几乎不受影响。

  • 恢复速度快:数据恢复时直接加载二进制文件,比 AOF 快。

  • 文件紧凑:RDB 文件是压缩的二进制格式,适合备份和灾难恢复。

缺点:

  • 可能丢失数据:两次快照之间的数据修改会丢失(取决于保存周期)。

  • 大数据集时 fork 可能延迟服务:如果数据集很大,fork 子进程可能耗时较长(但通常仍比 AOF 重写影响小)。


2. AOF(追加文件持久化)

AOF 记录所有写操作命令(以 Redis 协议格式),并在重启时重新执行这些命令来恢复数据。

工作原理:

  • 每个写命令都会被追加到 AOF 缓冲区,然后根据策略同步到磁盘。

  • 随着时间推移 AOF 文件会变大,Redis 提供 BGREWRITEAOF 来重写 AOF 文件(移除冗余命令,压缩文件)。

  • 重写通过子进程完成,期间新的写操作会被记录到新 AOF 文件和缓冲区。

同步策略(appendfsync):

bash 复制代码
appendonly yes
appendfsync always    # 每个写命令都同步到磁盘,最安全但性能最低
appendfsync everysec  # 每秒同步一次(默认推荐)
appendfsync no        # 由操作系统决定何时同步,性能最好但可能丢失更多数据

优点:

  • 数据安全性高 :根据策略可以做到几乎零数据丢失(如 appendfsync always)。

  • 可读性好:AOF 文件是文本格式,便于人工查看和修复。

  • 日志自动重写:避免文件无限增长。

缺点:

  • 文件通常比 RDB 大:即使经过重写,AOF 文件仍可能比 RDB 大。

  • 恢复速度慢:重放所有命令可能比加载 RDB 慢得多。

  • 写性能略有影响 :根据同步策略,可能对吞吐量有影响(但 everysec 通常可接受)。


3. 如何选择与混合使用

单独使用场景:

  • 只用 RDB:可以容忍分钟级数据丢失,追求快速恢复和备份效率的场景。

  • 只用 AOF:对数据安全性要求极高,可以接受稍慢的恢复速度。

混合持久化(Redis 4.0+):

可以同时开启 RDB 和 AOF,兼具两者优势:

  • AOF 用于保证数据安全性。

  • RDB 用于快速备份和恢复,同时 AOF 重写时会使用 RDB 格式作为基础数据,再追加增量命令,生成混合格式文件(aof-use-rdb-preamble yes)。

配置建议(通用场景):


4. 注意事项

  • 监控磁盘空间:AOF 文件可能增长很快,尤其是在写操作频繁时。

  • 备份策略:无论使用哪种方式,都应定期将持久化文件备份到其他服务器或云存储。

  • 性能测试:根据业务场景进行压力测试,选择合适的持久化策略和参数。

拓展:

bgsave的执行原理

执行BGSAVE时,Redis主进程会fork()出一个子进程 。fork瞬间,子进程获得主进程完全相同的内存映射(页表) ,但此时实际物理内存并未复制 ,父子进程共享同一份物理内存,子进程开始将此刻的内存数据快照写入磁盘RDB文件 。在此期间,主进程继续正常处理所有客户端请求 。当有新的写请求 需要修改某块内存时,操作系统会检测到该内存页正在被子进程读取,于是触发Copy-on-Write机制

  1. 复制 :将被修改的原内存页复制一份新副本

  2. 修改 :主进程修改新副本,继续服务

  3. 保持原内存页保持不变供子进程继续读取

子进程始终看到fork时刻的数据快照 ,不受主进程后续修改的影响。写入完成后,子进程退出,原内存种被复制的那部分数据被释放 ,主进程则一直使用修改后的新副本继续运行。

整个过程无需锁定数据,保证了Redis的高性能服务

aof优化:bgrewriteof

相关推荐
剩下了什么7 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥7 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉7 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变7 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记9 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里10 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科10 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦10 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
indexsunny11 小时前
互联网大厂Java面试实战:Spring Boot微服务在电商场景中的应用与挑战
java·spring boot·redis·微服务·kafka·spring security·电商
晚霞的不甘12 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d