Redis AOF 持久化:银行的 “交易流水单” 管理逻辑

目录

[一、AOF 的核心逻辑:"每笔交易都记流水"](#一、AOF 的核心逻辑:“每笔交易都记流水”)

[二、AOF 的三个步骤:从 "临时记录" 到 "正式归档"](#二、AOF 的三个步骤:从 “临时记录” 到 “正式归档”)

[1. 命令追加:记到 "临时小本本"](#1. 命令追加:记到 “临时小本本”)

[2. 写入与同步:抄到 "正式流水册"](#2. 写入与同步:抄到 “正式流水册”)

[3. AOF 还原:拿 "流水册" 重放交易](#3. AOF 还原:拿 “流水册” 重放交易)

[三、AOF 重写:给 "流水册" 瘦身(解决文件膨胀)](#三、AOF 重写:给 “流水册” 瘦身(解决文件膨胀))

[重写逻辑:派 "实习生(子进程)" 写 "精简流水册"](#重写逻辑:派 “实习生(子进程)” 写 “精简流水册”)

四、衔接之前的结构知识


如果把 Redis 比作银行的核心交易系统(处理存款、取款、转账等 "写操作"),那么 AOF 持久化就像银行的 "交易流水单"------ 通过记录 "每一笔交易命令",确保系统故障后能还原所有账户的最终状态。

一、AOF 的核心逻辑:"每笔交易都记流水"

与 RDB"定期拍纸质账本快照(全量备份)" 不同,AOF 是 "实时记录交易命令(增量备份)":

  • RDB 像 "每月拍一次金库账本的照片";
  • AOF 像 "每笔交易都记在流水单上"。

二、AOF 的三个步骤:从 "临时记录" 到 "正式归档"

1. 命令追加:记到 "临时小本本"

cpp 复制代码
struct redisServer {
    // ...
    // AOF缓冲区,每次追加到 aof_buf 末尾
    sds aof_buf;
    // ...
};

银行柜员每完成一笔交易(如 "给用户 A 存 100 元",对应 Redis 的SET user:A 100命令),会立刻把交易内容按固定格式(Redis 协议)写进 "临时小本本"(aof_buf缓冲区)

  • 类比:Redis 执行完写命令后,把命令丢进aof_buf临时存着,等后续统一归档。

2. 写入与同步:抄到 "正式流水册"

银行有个 "归档员"(flushAppendOnlyFile函数),负责把 "临时小本本" 的内容抄到 "正式流水册(AOF 文件)"。抄的严格程度appendfsync选项决定,对应三种策略:

appendfsync选项 银行场景类比(归档规则) 技术特点
always 每笔交易后,立刻抄到流水册并强制存进保险箱 最安全(最多丢 1 笔交易),但最慢(柜员总在等归档)
everysec 每秒抄一次流水册,用小助手(子线程)每秒强制存保险箱 平衡安全与性能(最多丢 1 秒交易),Redis 默认选择
no 只抄到流水册,啥时候存保险箱交给银行后台(操作系统) 最快,但最不安全(后台可能延迟很久存,停电丢多笔)

3. AOF 还原:拿 "流水册" 重放交易

如果银行核心系统故障,要恢复数据,就把 "正式流水册(AOF 文件)" 里的交易,从头到尾再做一遍

  • 银行找个 "模拟柜员"(伪客户端,无网络连接但能执行命令),照着流水册的记录,重新执行每一笔交易(如 "给用户 A 存 100 元""给用户 B 转 50 元"),最终还原所有账户的余额。

三、AOF 重写:给 "流水册" 瘦身(解决文件膨胀)

问题:流水册会越来越厚

比如反复操作同一个账户:

复制代码
RPUSH list "A" "B"   # list变成["A","B"]
RPUSH list "C"       # list变成["A","B","C"]
LPOP list            # list变成["B","C"]
RPUSH list "D" "E"   # list变成["B","C","D","E"]

流水册里会记 4 条命令,但最终 list 是["B","C","D","E"]

  • 显然,用 一条RPUSH list "B" "C" "D" "E" 就能代替这 4 条,却能达到同样效果。

重写逻辑:派 "实习生(子进程)" 写 "精简流水册"

为了让流水册变薄,银行会做 "流水册重写":

  1. 派实习生(子进程) :子进程先看当前所有账户的最终状态 (比如直接查 list 的最终元素是["B","C","D","E"])。

  2. 生成最简命令 :用一条RPUSH list "B" "C" "D" "E"代替原来的 4 条命令,写一本 "精简流水册"。

  3. 处理重写期间的新交易 :重写时,新交易(如RPUSH list "F")会同时记到 "原来的流水册" 和 "重写小缓冲区"。

  4. 最终替换 :实习生写完 "精简流水册" 后,银行把 "重写小缓冲区" 里的新交易(RPUSH list "F")追加到新流水册末尾,然后用新流水册替换旧的 ------ 这样新流水册既包含所有最终状态,又没有冗余命令。

四、衔接之前的结构知识

  • 与 RDB 互补 :RDB 是 "定期全量备份(像每月拍账本照片)",恢复快但实时性差;AOF 是 "增量交易记录(像流水单)",实时性好但恢复慢、文件易膨胀。Redis 通常结合两者:用 RDB 做基础全量备份,用 AOF 做增量补充,保障数据安全。

  • 与内存对象关联 :AOF 记录的 "写命令",操作的是 Redis 内存中的字符串、列表、哈希等对象;重写时,子进程直接读取内存中对象的最终状态(如列表的最终元素),再生成最简命令,避免解析旧 AOF 的冗余命令。

这样,AOF 就像银行 "既实时记流水,又定期给流水瘦身" 的策略 ------ 既保证交易可追溯,又避免流水册无限膨胀。

相关推荐
老邓计算机毕设3 小时前
Springboot乐家流浪猫管理系统16lxw(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
每天进步一点_JL3 小时前
InnoDB 存储引擎深度解析:从 B+ 树到全文索引的底层实现
数据库
未来影子4 小时前
系统炸了?数据库单表存了七十亿条数据
数据库
麦兜*4 小时前
MongoDB 高可用部署:Replica Set 搭建与故障转移测试
java·数据库·spring boot·后端·mongodb·spring cloud·系统架构
DemonAvenger4 小时前
分库分表实战:应对数据增长的扩展策略
数据库·sql·性能优化
keep__go4 小时前
postgresql9.2.4 离线安装
linux·运维·数据库·postgresql
IvorySQL4 小时前
当数据库宕机时,PostgreSQL 高可用在背后做了什么?
数据库·postgresql
盒马coding4 小时前
PostgreSQL与SQL Server:B树索引差异及去重的优势
数据库·postgresql
^辞安4 小时前
MVCC是如何工作的?
数据库·oracle·mvcc