对于AOF模块和命令层交互的理解

AOF 在 TinyRedis 里是旁路持久化模块,插在写命令执行链路旁边。普通客户端写命令执行成功后,CommandDispatcher 会通过 appendIfNeeded 判断是否需要写 AOF;如果是写命令、AOF 开启、并且不是 AOF replay 或复制回放,就调用 AOF::appendCommand,把 argv 编码成 RESP Array 追加到 appendonly.aof。

服务启动时,EpollServer::init 会先调用 CommandDispatcher::loadAof。loadAof 本身不直接读文件,而是调用 AOF::replay。AOF::replay 负责读取 AOF 文件,用 RESPParser 解析命令,再用 CommandParser 转成 argv;每解析出一条 argv,就通过 lambda 回调给 CommandDispatcher,执行 dispatchInternal(argv, true),把命令回放到 InMemoryDB。这里传 true 是为了避免 replay 过程中再次追加 AOF,也避免 replica 的 READONLY 逻辑影响内部回放。

AOF 的刷盘策略有 always、everysec、no 三种。always 是每次追加后立即 fsync;everysec 是追加后只标记 dirty_,由 cron 周期调用 flushIfNeeded,在距离上次 fsync 超过约 1 秒时刷盘;no 则不主动 fsync,交给操作系统。everysec 是性能和安全性的折中,宕机最多可能丢最近约 1 秒数据。

AOF rewrite 用于压缩 AOF 文件,不是定时每秒执行。REWRITEAOF 是同步 rewrite,会通过 snapshotCommands 从当前内存状态生成 SET/HSET/EXPIRE 等最小恢复命令,写入临时文件,fsync 后 rename 原子替换旧 AOF。BGREWRITEAOF 是后台 rewrite,startBackgroundRewrite 用后台线程写快照临时文件,主线程继续处理请求;rewrite 期间的新写命令正常追加旧 AOF,同时额外进入 backgroundRewriteBuffer_。后台完成后,pollBackgroundRewrite 在主线程收尾,把 buffer 追加到新临时文件末尾,再 rename 替换旧 AOF,保证 rewrite 期间的新写入不丢。

相关推荐
Crazy________22 分钟前
Redis03:持久化存储,大key分析,主从复制及哨兵模式
数据库·redis·容器
范什么特西2 小时前
redis题目面渣重点
数据库·redis·缓存
xcLeigh3 小时前
Go入门:短变量声明的陷阱与最佳实践
java·redis·golang·教程·变量
油丶酸萝卜别吃7 小时前
Redis 布隆过滤器快速实现
数据库·redis·缓存
MC皮蛋侠客1 天前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis
渣渣盟1 天前
当 Redis 写入成为性能瓶颈时,如何利用 异步批量 Sink 将吞吐量从 1w QPS 提升到 10w+?
数据库·redis·php
MC皮蛋侠客1 天前
Redis 系列(六):过期、内存淘汰与内存优化——让 Redis 活得更久
数据库·redis·bootstrap
MC皮蛋侠客1 天前
Redis 系列(七):事务、Pipeline 与 Lua 脚本——从原子性到 Functions
数据库·redis·lua
MC皮蛋侠客1 天前
Redis 系列(八):缓存设计模式与一致性——从 Cache Aside 到防雪崩
redis·缓存·设计模式
渣渣盟1 天前
当 Redis 写入不再是瓶颈后,Flink 任务的反压可能来自哪里?如何系统性地定位和解决 Flink 反压问题?
数据库·redis·flink