对于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 期间的新写入不丢。

相关推荐
aiks_yuan5 小时前
Redis 大key怎么排查和删除:--bigkeys 每类只报一个,DEL 百万字段的 Hash 卡 0.3 秒(Redis 7.2 实测)
redis
羑悻的小杀马特8 小时前
Redis持久化三剑客:RDB二进制快照、AOF文本日志、混合模式如何守护你的数据安全?
数据库·redis·缓存·aof·持久化存储·rdb
时间的拾荒人9 小时前
Redis 进阶实战:渐进式遍历、持久化机制与事务详解
数据库·redis·缓存
码哥字节1 天前
缓存一致性:先删缓存还是先更新库?3 种方案对比 + 实战
redis
2501_933923251 天前
解读Redis:单线程模型
数据库·redis·缓存
我不会起名字3221 天前
seq 空洞排查:Mongo 的 51 只是预留上界,Redis CURR 才是已消耗边界
redis·后端·mongodb·go·即时通讯·im·故障排查
时间的拾荒人1 天前
Redis 集合类型详解:Set 与 Zset
redis·缓存·面试
鶴哥只手遮天1 天前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源