Redis-持久化

redis虽然是一个内存数据库,但数据存在内存中是不持久的,想要持久化存储还得把数据存在硬盘上,redis也会把数据存在硬盘上,只不过这硬盘数据是用来恢复redis在内存的存储的,实际上读写还是在内存。

Redis 支持 RDB 和 AOF 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。

前置知识:redis属于客户端服务器类型,同时内部是单线程模型

一、RDB---定期备份

RDB可以定期地把redis中的数据备份到硬盘中,用来恢复内存数据,就相当于"快照"

1.1触发机制

RDB有手动,自动两种触发机制。

手动触发对应 save和bgsave命令

  • save命令 :执行save会使redis全力以赴去进行数据复制,这时候会阻塞redis客户端其他操作,坏处类似(key *)基本不会使用这个命令
  • bgsave命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动
    结束。阻塞只发生在 fork 阶段,⼀般时间很短。

redis内部进行RDB操作,基本都使用类似bgsave方式
bgsave流程:

1.执行 bgsave 命令,Redis 父进程判断当前是否存在其他正在执行的子进程(如 RDB/AOF 子进程),如果存在,bgsave 命令直接返回。

2.父进程执行 fork 创建子进程,fork 过程中父进程会阻塞。通过 info stats 命令查看 latest_fork_usec 选项,可以获取最近一次 fork 操作的耗时,单位为微秒。

3.父进程 fork 完成后,bgsave 命令返回 "Background saving started" 信息,不再阻塞父进程,父进程可以继续响应其他命令。

4.子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB 的时间,对应 info 统计中的 rdb_last_save_time 选项。

5.子进程发送信号给父进程表示完成,父进程更新统计信息。

自动触发

1.通过save配置,比如save m n表示"数据在m秒内发生n次修改"就自动触发。

2.从节点进行全量复制时,主节点自动触发,然后将RDB文件交给从节点

3.shutdown命令关闭redis时触发

redis配置文件中的一些默认配置

1.2 RDB文件

RDB操作会产生RDB文件

RDB的文件内容是默认通过"LZF"算法进行压缩 处理的二进制数据文件

虽然压缩会消耗CPU但可以大大降低文件体积,所以还是尽量开着

RDB文件内容千万不要擅自修改,redis重启会尝试加载RDB文件,如果文件被改坏了可能会导致redis服务器无法启动

RDB文件只有一份,进行"快照操作"时会先创建一个临时RDB文件,等复制好了就会替换,新文件的Inode会更新,可以根据这个判断文件新旧。

1.3 RDB优缺点

  • RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适用于备份、全量复制等场景。例如每 6 小时执行 bgsave 备份,并把 RDB 文件复制到远程机器或文件系统(如 HDFS)中用于灾备。

  • Redis 加载 RDB 恢复数据的速度远快于 AOF 方式。

  • RDB 方式无法做到实时持久化或秒级持久化。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高。

  • RDB 文件使用特定二进制格式保存,Redis 版本演进过程中存在多个 RDB 版本,兼容性可能存在风险。

二、AOF---实时备份

上述说到RDB是一个定期备份操作,如果在完成一次备份后,瞬间涌入大量操作,redis还没来得及自动备份就炸了,那数据不是都丢了吗?

这里AOF就能解决这个问题

先做一个了解,AOF文件是文本文件,AOF是默认关闭的,开启AOF后redis就通过AOF来恢复数据不再用RDB了。

2.1 AOF工作流程

redis要求的就是"快",使用AOF又读内存又写硬盘的,这能快吗?

其实没影响,AOF是把数据都写到一个内存缓冲区 ,写的差不多的时候在一并写入硬盘(有效减少磁盘IO),而且AOF写入硬盘是"顺序写入 ",硬盘在"顺序读写"的时候会更快一些

1.所有的写入命令会追加到 aof_buf(缓冲区)中。

2.AOF 缓冲区根据对应的策略向硬盘做同步操作。

3.随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。

4.当 Redis 服务器启动时,可以加载 AOF 文件进行数据恢复。

2.2 缓存区文件同步

AOF还有一个问题,如果我在写入缓冲区的时候,redis炸了可咋办,数据丢了吗?

对于redis来说确实丢了,不过我们可以牺牲性能来提高缓存刷新频率进而提高可靠性

AOF 缓冲区同步文件策略:从上到下频率越来越低,一般用第二个

可配置值 说明
always 命令写入 aof_buf 后调用 fsync 同步,完成后返回
everysec 命令写入 aof_buf 后只执行 write 操作,不进行 fsync。每秒由同步线程进行 fsync
no 命令写入 aof_buf 后只执行 write 操作,由 OS 控制 fsync 频率

2.3 重写机制

AOF 重写是 Redis 解决 AOF 文件体积膨胀、优化数据恢复效率的核心手段。

2.3.1 为什么 AOF 重写能缩小文件?

AOF 重写并不需要读取、分析或合并旧的 AOF 文件,而是直接读取 Redis 内存中的当前键值对状态来生成新文件。其缩小体积的逻辑如下:

  • 丢弃过期数据:已经过期的数据在内存中可能已被删除或不再有效,重写时不会将其写入新文件。
  • 剔除无效命令 :旧日志中大量的中间状态(如 SET a 1, SET a 2, SET a 3)在重写时只会被简化为最终状态(SET a 3)。
  • 删除已删除的数据 :例如先 SET key val 后又 DEL key,这两条指令在重写后的文件中都会消失。
  • 合并多条指令 :对于集合类操作,多条插入指令(如 100 次 Lpush)会被合并为一条指令(Lpush list v1 v2 ... v100),极大地节省了报头空间。

2.3.2 AOF 重写的触发条件

重写可以通过手动干预或配置参数自动触发:

① 手动触发

  • 客户端直接执行命令:BGREWRITEAOF

② 自动触发

基于 redis.conf 中的两个关键配置参数:

  • auto-aof-rewrite-percentage 100
    • 表示当前 AOF 文件大小超过上一次重写后文件大小的百分之多少时触发。100 意味着文件体积翻倍时触发。
  • auto-aof-rewrite-min-size 64mb
    • 表示触发重写的最小文件体积。防止在文件还很小时(例如只有几 KB)就频繁进行重写操作。

2.3.3 AOF 重写的详细流程

AOF 重写采用 "后台子进程" 方式执行,确保主进程可以继续处理客户端请求。

详细步骤:

  1. 创建子进程 (Fork)
    • 主进程调用 fork() 创建子进程。子进程与主进程共享此时的内存快照。
  2. 子进程后台重写
    • 子进程遍历内存数据,将每个键值对转换成 Redis 命令写入到新的临时 AOF 文件中。
  3. 主进程同步处理增量 (Rewrite Buffer)
    • 在子进程重写期间,主进程仍在处理新的写请求。
    • 这些新产生的写命令会被同时写入 AOF 缓冲区 (保证旧 AOF 完整性)和 AOF 重写缓冲区(图3.2)(保证新 AOF 不丢失重写期间的数据)。
  4. 子进程完成通报
    • 子进程写完内存快照后,向主进程发送一个信号。
  5. 增量数据补录 (关键阻塞点)
    • 主进程收到信号后,会将 AOF 重写缓冲区 中的所有增量命令写入到新的临时 AOF 文件中。
    • 注意:此步骤由主进程执行,会产生短暂阻塞。
  6. 原子替换
    • 主进程使用新的 AOF 文件原子地覆盖旧文件,至此重写完成。


图3.1存在意义:你在写新的AOF文件时redis炸了,就靠对老文件的修改来完成"实时备份"

提示 :从 Redis 7.0 开始,引入了 Multi-Part AOF,取消了复杂的"重写缓冲区",改用增量 AOF 文件(Incr AOF)来存储重写期间的数据,进一步降低了主进程的阻塞风险和内存消耗。

三、混合持久化

AOF是文本数据,读写成本很高,这时就引入了混合持久化,把AOF和RDB优点一同纳入
就一个修改点:在AOF触发重写时,将重写数据改为RDB那种二进制格式

AOF与RDB优先级:AOF更优

相关推荐
yjb.gz2 小时前
Shell实现数据库巡检
数据库
福大大架构师每日一题2 小时前
redis 8.4.1 正式发布:安全升级、性能强化与多模块重大修复详解
数据库·redis·安全
魑-魅-魍-魉3 小时前
金仓数据库(KingbaseES)Windows 安装避坑指南:从 Connection Refused 到服务启动的完整实战记录
数据库·金仓
chlk1234 小时前
聊聊索引:为何 B + 树能撑起数据库的半壁江山?
数据库·mysql
宁酱醇4 小时前
ORACLE_建表+增改查+删
数据库·oracle
爬山算法4 小时前
MongoDB(8)什么是聚合(Aggregation)?
数据库·mongodb
Tinyundg4 小时前
CentOS安装Oracle 19C 数据库
数据库·oracle·centos
IT_Octopus4 小时前
AI 工程 生产级别向量数据库Milvus2.6.10性能测试报告
数据库·人工智能·milvus
JosieBook4 小时前
【数据库】时序数据库选型指南:从大数据角度解析IoTDB的优势
大数据·数据库·时序数据库