StatsD 是什麼#

StatsD 是一個用 Node.js 寫成的 Daemon,由 Etsy 在 2011 年開源,主要工作是接收應用程式或 Exporter 發送的指標(計數、計時、瞬時值等),再將其轉送到後端儲存。最常見的搭配是 Graphite。雖然 Etsy 是 StatsD 廣為人知的推手,但其實它的設計靈感來自 Flickr 在 2008 年用 Perl 寫的同名工具,Etsy 是重新優化實作的版本。

Etsy 在 2010 年實現了持續部署(Continuous Deployment),把網站部署從原本需要四人合力、耗時一小時的流程縮短到一人兩分鐘搞定。為了在快速部署下不犧牲品質,他們需要即時的 Metrics 來判斷服務狀態,於是重寫 StatsD。

Metrics 類型#

StatsD 的指標格式大致為:

<metric_name>:<value>|<type>

主要有三種類型:

  • Counter 計數:從 0 開始,可加正整數但不可減少;常用於請求總數、錯誤次數。每當 StatsD 把資料送往後端時,內部值會被重置為 0。例如:request_total:1|c
  • Timer 計時:用於量測操作所需時間(毫秒),並可衍生平均、最大、最小、百分位數等統計值。例如:request_duration:100|ms
  • Gauge 量測:可任意增減的數值,常用於記憶體使用、活躍使用者數量。可指定值 active_users:100|g、增加值 active_users:+20|g 或減少值 active_users:-10|g

為什麼用 UDP#

StatsD 預設透過 UDP 收指標。Etsy 一開始就強調,UDP 的好處是:

  • 速度快、訊息送出後不等回應,對應用程式效能影響極小。
  • 即便 StatsD 故障,應用程式不會被卡住或受影響。

代價是 UDP 不保證送達,可能造成指標丟失或不完整。但因為指標多半是輔助性質、丟失部分資料對主要業務影響有限,這個權衡通常可以接受。

StatsD Library#

StatsD 本身只負責「收」,指標的生成與送出仍要靠應用程式。常見的 Library:

  • Python:pystatsd、datadog。
  • Node.js:hot-shots。
  • Java:java-dogstatsd-client。

DataDog 與 DogStatsD#

DataDog 是一家提供監控服務的 SaaS 公司。他們在 StatsD 的基礎上重新設計了 DogStatsD,沿用 UDP 傳輸但增加了:

  • Histogram、Distribution 等更多指標類型。
  • Tagging 功能,類似 Prometheus 的 Label。

讓 DataDog 的指標收集與分析更接近 Prometheus 的使用體驗。

StatsD Exporter#

如果想保留 UDP 收指標的高效能,又希望沿用 Prometheus 作為儲存與查詢,可以用 Prometheus 團隊開發的 StatsD Exporter:它以 UDP 接收 StatsD 格式的資料,再轉成 Prometheus 格式供 Prometheus 抓取。若需要更完整的 Label 支援,建議搭配 DogStatsD 的 Library 一起使用。

工具名稱結尾常見的 D 指的是 Daemon,意指背景常駐執行的程式,例如本章的 StatsD、收集 Log 的 Fluentd 等。

Lab 摘要#

範例 11-statsd 提供兩種啟動方式。

StatsD + Graphite#

docker-compose up -d

主要服務:

  • FlaskAPI:http://localhost:8000
  • Graphite Web UI:http://localhost
  • Grafana:http://localhost:3000,預設 admin/admin

可透過瀏覽器或 k6 對 FlaskAPI 發送 Request:

k6 run --vus 1 --duration 300s k6-script.js

確認指標:在 Graphite Web UI 展開 Metrics > stats > timers > flask > request_durations_seconds > count。

關閉:

docker-compose down

StatsD Exporter + Prometheus#

docker-compose -f docker-compose.exporter.yaml up -d

主要服務:

  • FlaskAPI:http://localhost:8000
  • StatsD Exporter:http://localhost:9102/metrics
  • Prometheus:http://localhost:9090
  • Grafana:http://localhost:3000,內建 Provisioning Dashboard:Flask Monitoring。

關閉:

docker-compose -f docker-compose.exporter.yaml down

Lab 達成的目標:

  • 透過 StatsD 收集 Flask API 的 Metrics。
  • StatsD + Graphite:使用 graphiteapp/docker-graphite-statsd 把 StatsD 與 Graphite 一起跑起來;Flask API 用標準 StatsD Library pystatsd 產生 Metrics。
  • StatsD Exporter + Prometheus:用 StatsD Exporter 將 StatsD 資料轉成 Prometheus Metrics;Flask API 改用 DataDog 重寫的 DogStatsD Library 產生 Metrics。

小結#

近年較少聽到有人新採用 StatsD,但在某些情境下它仍有其價值:

  • 應用程式對效能極度敏感、無法承受同步暴露 /metrics
  • 應用程式無法提供 HTTP Endpoint 供 Prometheus 抓取。
  • 沿用既有工具的內建 StatsD 輸出(例如 Gunicorn 的內建監控)。

雖然 StatsD 沒有列在 CNCF 的 Observability Tool 中,但在維運老前輩心中仍是很有感情的選項,也是接觸監控的人很常遇到的第一個工具。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10327856