StatsD 是什麼#

StatsD 是一個輕量級的指標收集協議,最初由 Etsy 在 2011 年開源。它不是資料庫,不是查詢引擎,也不是視覺化工具——它只做一件事:用最低的開銷,把應用程式產生的指標資料送出去

StatsD 的架構非常簡單:

  • 應用程式透過 StatsD Client Library 發送指標
  • StatsD Daemon(伺服器端)接收、聚合,然後轉發到後端儲存系統
  • 傳輸協議使用 UDP

這個簡潔的設計背後,藏著一個明確的工程取捨:指標收集絕對不能影響應用程式的效能

為什麼用 UDP#

StatsD 選擇 UDP 作為傳輸協議,這是整個設計中最關鍵的決策。

Fire-and-Forget 的哲學#

UDP 是「射後不理」的協議——發送端丟出封包後不等待確認、不重試、不建立連線。這意味著:

  • 不阻塞應用程式:即使 StatsD Daemon 完全掛掉,應用程式的指標發送程式碼也只是把封包丟進虛空,不會卡住任何執行緒
  • 無連線開銷:不需要 TCP 的三次握手、Keep-alive、連線池管理
  • 延遲極低:一次 UDP 發送通常在微秒等級完成

可以接受丟失嗎?#

UDP 不保證送達,封包確實可能丟失。但對於指標資料來說,這是一個合理的取捨

  • 指標是統計性的數據,偶爾丟失幾個資料點不會影響整體趨勢
  • 比起丟失少量指標,讓應用程式因為指標收集而變慢是更嚴重的問題
  • 在正常網路環境下(本機或同機房),UDP 的丟包率極低

判斷該不該用 UDP 傳指標的簡單原則:如果丟失 0.1% 的指標資料點會造成業務問題,你可能需要的是 Log 而不是 Metrics。指標天生就是可以容忍少量損失的統計資料。

Metric Types#

StatsD 定義了四種基本的指標類型,每種對應不同的使用場景。

Counter#

累計計數器,記錄事件發生的次數。

  • 每次呼叫都是「加 N」的操作
  • StatsD Daemon 在 Flush Interval(通常 10 秒)內聚合後送出
  • 典型用途:請求次數、錯誤次數、訂單數量

Timer#

計時器,記錄某個操作花了多久。

  • 發送的是每次操作的持續時間(毫秒)
  • StatsD Daemon 自動計算 Mean、Median、P90、P99 等統計值
  • 典型用途:API 回應時間、資料庫查詢時間、任務處理時間

Timer 是 StatsD 最強大的指標類型。你只需要發送原始的時間數值,Daemon 端會自動幫你算出各種百分位數。相較之下,Prometheus 要達到類似效果需要使用 Histogram 或 Summary,在 Client 端就得做更多計算。

Gauge#

瞬時量規,記錄某個值的當前狀態。

  • 可以設定絕對值,也可以做相對增減
  • 不會在 Flush 時被重置,保持最後設定的值
  • 典型用途:記憶體使用量、佇列長度、連線數

Set#

集合,記錄不重複的值的數量。

  • 在 Flush Interval 內自動去重
  • 典型用途:活躍使用者數(Unique Users)、不重複 IP 數量

StatsD Library 的角色#

StatsD Client Library 是嵌入在應用程式中的輕量套件,它的設計原則是盡可能不影響宿主應用

  • 大多數語言的 Client Library 都支援 Sampling(抽樣):例如只發送 10% 的資料點,由 Daemon 端還原真實數值,進一步降低網路開銷
  • Client Library 通常提供批次發送:將多筆指標打包成一個 UDP 封包
  • 初始化失敗時通常會靜默降級(Silent Degradation),不會拋出例外影響應用程式啟動

雖然 StatsD Client 設計為低開銷,但在極端高吞吐量下(每秒數十萬筆指標),仍需注意 UDP Buffer 溢出的問題。這時候 Sampling 不是可選的優化,而是必要的措施。

StatsD Exporter:與 Prometheus 的橋樑#

StatsD 和 Prometheus 各自有不同的資料模型和收集方式,StatsD Exporter 扮演的是翻譯官的角色:

  • 它同時監聽 StatsD 協議(UDP)和提供 Prometheus 的 /metrics 端點(HTTP)
  • 將 StatsD 的 Counter、Timer、Gauge 映射為 Prometheus 對應的 Metric Type
  • 支援映射規則(Mapping Rules),讓你控制 StatsD 指標名稱如何轉換為 Prometheus 的 Label 結構

這讓你可以在同一個監控平台中統一查看來自 StatsD 和 Prometheus 兩個體系的指標。

什麼時候該用 StatsD#

適合 StatsD 的場景#

  • 高吞吐量、低延遲要求:遊戲伺服器每秒處理數萬個事件,廣告競價系統在毫秒內完成決策,高頻交易系統對每一微秒都斤斤計較——這些場景中,任何阻塞式的指標收集都是不可接受的
  • 已有 StatsD 生態的環境:許多成熟的系統和框架原生支援 StatsD 協議,直接沿用比重新整合 Prometheus Client 更務實
  • 多語言環境中追求一致性:StatsD 協議極其簡單(就是 UDP 文字封包),幾乎任何語言都能在幾行程式碼內實現,不依賴官方 Client Library

直接用 Prometheus Client 就好的場景#

  • 一般的 Web 服務和 API:Prometheus Client Library 的開銷對大多數應用來說微乎其微
  • 需要豐富 Label 維度:Prometheus 的多維 Label 模型比 StatsD 的扁平命名空間更靈活
  • 已經是 Prometheus 生態系:額外引入 StatsD 只會增加架構複雜度

選擇 StatsD 還是 Prometheus Client 的核心問題是:指標收集的開銷對你的應用來說是否真的構成問題? 如果你的服務每秒處理幾百到幾千個請求,Prometheus Client 的 Pull 模式完全夠用。只有當你在效能的極端邊界上工作時,StatsD 的 UDP Fire-and-Forget 模式才真正展現價值。