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

相关推荐
CCPC不拿奖不改名2 小时前
SQL基础(SQL小白教程):MySQL语句+环境一键搭建+面试习题
数据库·sql·计算机网络·mysql·oracle·面试·职场和发展
陈文锦丫2 小时前
JAVA面试
数据库·mysql
sunfove2 小时前
将 Python 仿真工具部署并嵌入个人博客
开发语言·数据库·python
Codeking__2 小时前
Redis——基本通用命令
redis·git·github
冰清-小魔鱼3 小时前
各类数据存储结构总结
开发语言·数据结构·数据库
深藏bIue4 小时前
MongoDB 4.4.30安装、数据迁移
数据库·mongodb
benyuanone4 小时前
MySQL环境项目迁移成国产化达梦环境
数据库·mysql
北凉军4 小时前
java连接达梦数据库,用户名是其他库的名称无法指定库,所有mapper查询的都是以用户名相同的库内的表
java·开发语言·数据库
尽兴-4 小时前
MySQL索引优化:从理论到实战
数据库·mysql·优化·b+树·索引·最左前缀