已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
社区里对「双删 / 延迟双删 / MQ 失效」怎么选已经有不少讨论(见引用),我们线上也是「先更新 DB,再删 Redis」+ 延迟双删兜底,代码里延迟时间是一个写死的常量 500ms,注释写着「参考网上经验值」。
最近一次事故让我意识到这个数字经不起推敲:某天大促,主从复制延迟被大事务打到 2.3s,延迟双删的第二次删除在 500ms 就执行完了——结果从库还没追上主库,读请求打到从库读到旧值、回填缓存,脏窗口反而被「双删」合法化了一次。换句话说,延迟窗口小于复制延迟时,双删不但没兜住,还帮旧值又续了命。
所以我想把 500ms 改成动态值:延迟时间 = f(当前主从复制延迟 + 安全余量)。但卡在这个 f 怎么算、取数怎么取上。
Seconds_Behind_Master(或 8.0 的 Seconds_Behind_Source)是瞬时值,读它和用它之间已经变了;要不要取近 N 秒的 P99/P999?N 取多大?SHOW SLAVE STATUS / SHOW REPLICA STATUS 的 Seconds_Behind_Master,确认它只反映 SQL 线程 apply 的位点差,不含网络传输段;Exec_Master_Log_Pos vs Read_Master_Log_Pos)粗估了网络段延迟,但没形成稳定的计算式;pt-heartbeat 实测端到端复制延迟,但还没在压测环境跑过基线。引用了社区两条相关讨论作为上下文,避免重复讨论「选哪种策略」,这次只聚焦「延迟窗口这个数怎么来」。