5.5 KiB
P6 混合浸泡首跑基线与记分板三重伪击穿修复
- 日期: 2026-07-21;run_id:
soak_20260721_050750 - 结论: 8000 次调用全部完成,库自身零缺陷;记分板两项 FAIL 均为测量口径缺陷(三重伪击穿),修复后离线重裁全部 PASS。修复分支
fix/soak-scoreboard-clock。
1. 运行参数与规模
| 项 | 值 |
|---|---|
| 场景 | P6 混合(P1 .10 / P2 .20 / P3 .35 / P4 .15 / P5 .20),SOAK 五源故障池 |
| 预算/实际 | 8000 次(签字帽)/ 8000 次全部完成;token 1401 万(硬顶 2 亿) |
| 拓扑 | 2 worker × 32 并发 = 64 在途;限流/熔断/缓存全 Redis(db3);Postgres 遥测 |
| 用时 | 05:07–06:54,约 1h47m(3h 上限内) |
| 成本 | 23.42 元(价格表首次生效: 输入 2.1/输出 8.4 元/M tok;缓存命中 token=0 天然零成本) |
2. 结果基线(P6 首跑,后续回归对照)
| 指标 | 值 | 说明 |
|---|---|---|
| 总成功率 | 4648/8000 = 58.1% | 五源池 3 坏 1 紧闸;窗口成功率从开局 40% 爬至尾段 73%(熔断学习 + 缓存变热) |
| 缓存命中 | 2373 次 | P4 复读流量生效,命中秒回零成本 |
| 延迟(成功行) | 总时长 p50/p95 = 6.8s/48.1s;TTFT p50/p95 = 22.0s/53.2s | p50 远低于 P3 纯健康池(16.9s)系缓存命中行拉低;非缓存行与 P3 同量级 |
| P3 结构化成功率(P6 内嵌) | 0.218 | 故障池 + 网关 429 高压下的口径,不可与纯健康池基线 0.942 直接对比 |
| RSS | 实时 ps 采样: 10min 119MB → 40min 起稳定 36MB 至结束 | 无泄漏;峰值系 harness 自身无界入队(见 §4) |
错误分布大头(共 20146 遥测行): 网关侧 429 限速 4845(minimax_5 3773 + minimax_1 996 + minimax_4 76)、紧看门狗掐流 3622(inter_token 3390 + ttft 232)、真实空补全 2211、retry_exhausted 终态 3318、黑洞超时 230、坏 key 31。
治理行为实证: 黑洞源走完 攒失败→开路→仅探针漏过 全周期(全程 230 次超时,开路后每 5 分钟仅 1 次探针);坏 key 源 force_open 后基本从遥测消失;跑后记账归零、探针不悬挂、call_id 唯一全 PASS。
3. 三重伪击穿: RPM "FAIL" 根因链
记分板判 minimax_4(RPM=5)单分钟 6-10 次。逐层排查(每层修完仍 FAIL 才发现下一层):
| # | 口径缺陷 | 证据 | 修复 |
|---|---|---|---|
| 1 | 用完成时刻(created_at=落库时刻)聚桶,调用延迟达分钟级,多个准入窗口的调用挤进同一完成分钟 | 准入时刻 = created_at − latency 重算后分布改变 | 按准入时刻聚桶 |
| 2 | 用本机钟聚桶,而限流器窗口 id 来自 Redis 服务器钟(limiter.py:_window_id,CHS 移植的多进程口径统一设计) |
实测 Redis 钟偏移 +30.98s;密集分钟 10 次准入在第 ~29 秒恰可切 5+5 | 记分时实测偏移并校正;秒级截断噪声给 ±2s 贴边豁免(邻窗有余量才可豁免) |
| 3 | 缓存命中行计入 RPM——缓存在限流闸之前返回,未耗名额未打网关,但"遥测必录"使其带原源名落库 | minimax_4 共 579 行中 347 行 cache_hit=1(洋葱序 Telemetry→Cache→…→Retry 内限流,命中行 latency=0 从未过闸) | RPM 口径排除 cache_hit 行 |
修复后离线重裁(--rescore,不产流量): RPM PASS。精确说明(独立 verifier 复核): 剔除缓存行后仍有 2 个窗口 6 行,各含 1 行距右边界 0.2-0.7s——落在 created_at 秒级截断噪声的合理方向(截断只低估准入时刻,行只可能实属右邻窗),由分侧贴边豁免判为非击穿;并非"剔除后全部 ≤5"。verifier 另证明偏移敏感性: 就本数据集,offset=0 与 +31s 裁决相同(口径同源化仍是原则正确)。豁免逻辑经 verifier 对抗样例加固: 分侧(左贴边只可借左邻余量)+ 邻窗余量全局一次性消耗,防漏报真实击穿。
4. RSS "FAIL" 根因: 峰值口径 + 无界入队
_rss_mb用ru_maxrss——历史峰值只增不减;判"增长 782MB"实为开局峰值。- 峰值来源是 harness 自身: 分发循环 15 秒内把 4000 任务/worker(含 P2 ~313KB 图负载)全量
create_task,信号量只限执行不限入队;顺带使--max-hours截止检查随分发结束而失效、执行期无进度打印。 - 库无泄漏: 运行期实时 ps 采样 36MB 稳定 90 分钟(本 finding §2)。
修复: ① _rss_mb 改 ps -o rss= 当前值;② 分发改 _paced_dispatch 有界模式(先占并发名额再建任务),截止检查全程有效、内存峰值受限、进度行全程可见;③ 旧格式结果(仅峰值序列)重裁时判 SKIP 不判 FAIL。
5. 交付物
tools/soak/scoreboard.py:inv_rpm_never_exceeded新口径(准入时刻 + 服务器钟偏移 + 贴边豁免 + 排除缓存行)。tools/soak/run_soak.py:_rss_mb当前值、_paced_dispatch有界分发、_redis_clock_offset_s、--rescore RUN_ID离线重裁模式。- 测试:
tests/unit/test_soak_corpus.py新增 9 用例(先红后绿,含 2 个 verifier 对抗样例),全套 CI 绿覆盖 90%。 - 重裁报告:
tests/outputs/soak/soak_20260721_050750.md(全 PASS/SKIP)。
6. 经验沉淀
- 不变量的口径必须与执法者同源: 限流器用什么时钟、在哪个时刻、对哪些流量执法,记分板就必须用同样的三元组重算;任何一元错位都产生伪击穿。
- 分布式系统验收前先测时钟偏移(本实验室 Redis 快 ~31s)。
ru_maxrss不可用于"平稳性"断言;峰值与当前值是两个量。- "遥测必录"(含缓存命中)与"限流口径"(仅真实过闸流量)是两个集合,消费遥测时必须显式选择。