在分散式系統或微服務架構中,工程師經常會遇到一個詭異的現象:監控面板上每個單一服務的健康指標(Health Metrics)看起來都很正常,p50(中位數延遲)很快,p90 也可以接受,但整體的 p99 延遲卻高得離譜。
這種現象通常不是因為服務「故障(Failure)」,而是因為「掉隊者(Stragglers)」。
理解掉隊者與故障的區別
在處理延遲問題時,我們習慣直覺地使用重試(Retry)機制。但這裡有一個關鍵的技術誤區:故障與掉隊者是兩種完全不同的問題。
故障是指請求根本沒有完成(例如連線超時、伺服器崩潰)。對於故障,重試是正確的,因為原請求已經失敗,必須重新發送。
掉隊者是指請求最終會完成,但速度極慢。這可能是因為後端伺服器觸發了垃圾回收(GC Pause)、遇到了熱點分區(Hot Partition)或內核調度抖動。
如果對掉隊者使用重試,會產生嚴重的副作用。當一個請求因為後端壓力大而變慢時,你發送第二次重試請求,等於是在已經掙扎的後端增加了額外負擔。結果是後端壓力更大,導致更多請求變慢,p99 延遲反而惡化。
針對掉隊者的正確工具是對沖請求(Hedged Requests)。它的邏輯不是等待失敗,而是在原請求還在運行時,如果發現太慢,就主動發送一個備份請求,並採取「誰快用誰」的策略,一旦其中一個返回,立即取消另一個。
扇出架構中的延遲放大效應
為什麼單個服務 1% 的掉隊率會導致系統崩潰?這涉及到扇出(Fan-out)架構的機率問題。
在微服務中,一個頂層請求可能會調用 100 個下游服務。即便每個服務只有 1% 的掉隊機率,只要其中任何一個服務掉隊,整個頂層請求就會被拖慢。
根據機率計算,當扇出數量達到 100 個且單一服務掉隊率為 1% 時,約有 63% 的頂層請求會受到至少一個掉隊者的影響。這解釋了為什麼優化單一服務往往無法顯著改善系統整體的 p99 延遲,因為問題在於掉隊者的累積。
適應性對沖(Adaptive Hedging)的實作挑戰
對沖請求最困難的是決定「什麼時候發送備份請求」。
如果設定靜態閾值(例如 50ms),在生產環境中會失效。因為延遲分佈會隨流量峰值、新版本部署或時間段而漂移。太早發送會浪費資源,太晚發送則失去意義。
為了實現自動化且無需手動調優的對沖,需要一套適應性機制,包含以下三個核心組件:
第一,使用 DDSketch 進行即時分位數估計。 DDSketch 是一種量化草圖(Quantile Sketch)演算法,能在常數時間 O(1) 與固定記憶體空間內,估算出精確的延遲分位數(例如 p90)。它能讓系統實時學習當前流量的延遲分佈,並動態決定對沖的觸發點。
第二,引入滾動視窗(Tumbling Window)處理分佈漂移。 為了避免舊的延遲數據影響目前的判斷,系統會使用兩個 DDSketch 輪替(例如每 30 秒切換一次)。這樣可以確保對沖閾值能跟隨當前的系統狀態動態調整。
第三,利用令牌桶(Token Bucket)防止負載放大。 為了防止在真正的系統崩潰(所有請求都慢)時,對沖機制將流量翻倍導致雪崩,必須設定對沖預算。例如限制對沖請求不得超過總流量的 10%。當預算耗盡時,系統會停止對沖,讓服務優雅降級而非崩潰。
LLM 推論場景的特殊性:TTFT 與 TTFB
將此機制應用於大型語言模型(LLM)推論時,必須修正監控指標。
傳統 HTTP 服務監控的是 Header 返回時間,但 LLM 串流輸出中,Header 幾乎是立即返回的。真正的延遲在於首個 Token 生成時間(Time to First Token, TTFT)。
如果對沖機制監控的是 Header 時間,會導致幾乎所有請求都被判定為慢,從而觸發 100% 的對沖流量。正確的做法是將對沖計時器掛鉤在 Response Body 的第一個字節到達之時,這樣才能精準捕捉到因 KV-cache 缺失或預填充(Prefill)計算導致的掉隊者。
適用場景與限制
儘管適應性對沖能顯著降低 p99 延遲(實驗數據顯示可降低達 74%),但並非所有場景適用:
非冪等操作(Non-Idempotent):對沖會發送重複請求。如果操作涉及寫入或扣款,且後端沒有去重機制,會導致數據錯誤。 單一後端實例:如果所有請求都發往同一台機器,對沖只會增加該機器的壓力。 CPU 飽和:如果慢是因為 CPU 滿載,增加請求會加速崩潰。對沖最適合解決 GC 抖動或網路波動等瞬時問題。 嚴格限流的 API:如果第三方 API 有嚴格的每分鐘請求限制,對沖會快速消耗配額。
來源:infoq.com - Stragglers, Not Failures: How Adaptive Hedged Requests Reduce p99 Latency by 74 Percent
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。