it编程 > 数据库 > Redis

Redis 持久化与事务:RDB、AOF、MULTI/EXEC 与 WATCH 全解析

100人参与 • 2026-09-30 • Redis

redis 持久化有 ‌rdb(快照)‌ 和 ‌aof(追加日志)‌ 两种方式,生产环境建议开启 ‌aof(默认 everysec 刷盘)‌,追求极致恢复速度时可开启 ‌混合持久化‌。redis 事务 ‌不是真正的 acid 事务‌,它只保证命令按顺序批量执行且执行期间不被其他客户端插队,‌不支持回滚‌,运行时错误不会终止后续命令。如果你需要强原子性,更推荐用 ‌lua 脚本‌。

1. redis持久化机制(rdb与aof)

redis之所以快,是因为数据都在内存中
但为了防止进程崩溃或宕机导致数据丢失,必须将数据落盘,这就是持久化

1.1. rdb(redis database):内存快照

rdb是将当前进程的数据生成快照保存到硬盘的过程,生成的是紧凑压缩的二进制文件

1.1.1 触发机制

手动触发:

自动触发:

1.1.2 bgsave 运作流程

  1. 父进程判断当前是否存在正在执行的子进程(如rdb/aof子进程),存在则直接返回
  2. 父进程执行 fork 创建子进程(此阶段父进程阻塞,可通过 info stats 的 latest_fork_usec 查看耗时微秒数)
  3. 父进程 fork 完成后,返回 "background saving started",不再阻塞,继续响应其他命令
  4. 子进程根据父进程内存快照(copy-on-write,写时复制机制)生成临时rdb文件,完成后对原有文件进行原子替换
  5. 子进程发送信号给父进程,父进程更新统计信息(rdb_last_save_time)

父进程继续响应其他命令。利用linux的写时复制机制,子进程共享父进程的内存页,只有当父进程修改数据时,才会复制一份新的内存页。这保证了极低的性能损耗

1.1.3 优缺点

1.1.4 rdb文件的处理

1.2. aof(append only file):日志追加

aof以独立日志的方式记录每次写命令,重启时重新执行aof文件中的命令来恢复数据
目前是redis持久化的主流方式

开启 aof 功能需要设置配置:appendonly yes,默认不开启。aof 文件名通过 appendfilename 配置(默认是 appendonly.aof)设置。保存目录同 rdb 持久化方式一致,通过 dir 配置指定

1.2.1 工作流程(append -> sync -> rewrite -> load)

  1. 命令写入:所有写命令追加到 aof_buf(缓冲区)中
  2. 文件同步:根据策略将缓冲区同步到硬盘
  3. 文件重写:定期压缩aof文件
  4. 重启加载:启动时加载aof文件恢复数据

redis是单线程响应命令,如果每次都直接同步硬盘(io操作),性能会急剧下降。先写缓冲区可以减少io次数,同时允许提供多种同步策略来平衡性能与安全

1.2.2 文件同步策略(appendfsync)

redis 提供了多种 aof 缓冲区同步文件策略,由参数 appendfsync 控制

appendfsync 配置值说明fsync 时机建议
always命令写入 aof_buf 后调用 fsync 同步,完成后返回每次写入都执行 fsync除非是非常重要的数据,否则不建议配置
everysec命令写入 aof_buf 后只执行 write,不立即 fsync;每秒由同步线程执行一次 fsync每秒同步一次默认配置,也是推荐配置
no命令写入 aof_buf 后只执行 write,由操作系统控制 fsync 频率由 os 控制,不可控除非数据重要程度很低,一般不建议配置
对比项write 操作fsync 操作
核心机制延迟写(delayed write),利用 linux 内核页缓冲区强制硬盘同步
操作对象文件描述符 / 文件单个文件
返回时机写入系统缓冲区后立即返回阻塞直到数据写入硬盘
是否阻塞通常不阻塞阻塞
落盘保证不保证立即落盘,依赖系统调度强制同步,等待落盘完成
同步触发缓冲区页空间写满、达到特定时间周期等显式调用触发
故障风险同步前系统故障宕机,缓冲区内数据可能丢失调用返回后,正常情况下数据已写入硬盘
性能影响性能高,减少磁盘 io性能开销大,增加延迟
适用场景常规写入,追求吞吐量需要持久化保证的关键数据

1.2.3 aof重写机制

随着命令不断写入,aof文件会越来越大,redis引入重写机制来压缩体积

配置项说明默认值
auto-aof-rewrite-min-size表示触发重写时 aof 的最小文件大小64mb
auto-aof-rewrite-percentage表示当前 aof 占用大小相比较上次重写时增加的百分比—

aof重写流程与并发细节

  1. 执行重写请求
    如果当前进程正在执行 aof 重写,请求不执行;
    如果当前有bgsave在执行,则延迟到其完成后再执行
  2. 父进程 fork 创建子进程
  3. 关键并发处理:
    • 父进程继续响应其他命令。所有修改操作写入 aof_buf,并根据策略同步到旧aof文件,保证旧aof机制正确
    • 由于子进程只有 fork 之前的内存信息,父进程需要将 fork 之后的修改操作写入 aof_rewrite_buf(aof重写缓冲区)
  4. 子进程根据内存快照,将命令合并写入新的aof文件
  5. 子进程完成后发送信号给父进程
  6. 父进程将 aof_rewrite_buf 中的命令追加到新aof文件,并用新aof文件原子替换老aof文件

1.2.4 启动时数据恢复

当redis启动时,如果同时存在rdb和aof文件,优先加载aof(因为aof数据更全)。如果aof不存在,则加载rdb。如果加载损坏的文件,redis会拒绝启动(可用 redis-check-aof 或 redis-check-dump 修复)

通过 aof-use-rdb-preamble yes 开启。开启后,aof 重写时子进程先将当前内存数据以 rdb 格式写入新 aof 文件头部;重写期间及之后的新写命令以 aof 格式追加到文件后面。重启加载时,先加载 rdb 头部,再重放后续 aof 命令。这样既利用 rdb 加载快、体积小的优点,又保留 aof 的增量记录,降低数据丢失风险。但数据丢失窗口仍取决于 appendfsync 策略,且混合 aof 文件对旧版本 redis 和部分工具兼容性较差

2. redis事务与乐观锁

redis的事务与mysql的事务概念类似,都是将一系列操作绑定成一组批量执行,但在acid特性上有极大的弱化

2.1. redis事务的acid特性

2.2. 核心命令与执行流程

事务的错误处理

2.3. watch机制

在并发场景下,客户端可能先读取数据,再基于旧值构造事务进行修改。如果在提交事务前,该数据已被其他客户端修改,直接提交就可能造成数据不一致(如丢失更新)。redis 通过 watch 命令实现乐观锁(cas):watch 监视相关 key,若在 watch 之后、exec 之前这些 key 被修改过,则 exec 放弃执行整个事务并返回 nil,从而避免基于过期数据做出错误修改

2.3.1 watch 原理

2.3.2 实操演示

# 客户端1
watch k1          # 记录 k1 的版本号(假设是 0)
multi
set k1 100        # 入队,但不提交
set k2 1000       # 入队
# 客户端2(此时执行)
set k1 200        # 修改成功,k1 版本号变为 1
# 客户端1 再执行
exec              # 比对版本号:客户端是 0,服务器是 1。版本不一致!
(nil)             # 事务失败,所有命令都不执行

2.3.3 unwatch

取消对所有key的监控,相当于watch的逆操作
exec 和 discard 执行后,也会自动取消所有watch

watch 适合什么场景

watch 本质是cas(compare and swap)思路,在很多并发编程和数据库(如mysql的乐观锁)中都有应用。它适合读多写少的并发场景,如果在高并发写场景下,事务很容易因为版本冲突而不断重试失败,影响性能

3. 高频面试题 q&a 速查表

q1:rdb和aof的区别?如何选择

q2:aof重写时,主进程在做什么

q3:redis事务支持原子性吗

q4:watch命令的实现原理

q5:为什么redis执行bgsave时,不阻塞主进程

到此这篇关于redis 持久化与事务:rdb、aof、multi/exec 与 watch 全解析的文章就介绍到这了,更多相关redis 持久化与事务内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

赞 (0)

您想发表意见!!点此发布评论

推荐阅读

Redis持久化与事务机制原理、配置与避坑指南

09-30

Redis连接断开后实现自动重连的操作过程

09-30

Nginx+Lua+Redis实现动态封禁IP的几种方法

09-30

在Ubuntu上安装和使用Composer流程步骤

09-30

Redis 多机房同步实现主从跨地域复制延迟与数据一致性

10-01

Redis Cluster 高可用集群部署方案详解

09-29

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论