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 模式才真正展現價值。