圖片來源:iTHome
在開始前,先來看看這篇新聞「伺服器磁碟用罄,豐田被迫暫停所有汽車產線」,因為磁碟空間不足導致嚴重的停機事故,對於維運人員說猶如小當家中印上了「難吃印」的反派廚師。無論是哪種系統,都應謹慎處理磁碟空間不足的問題,當然也包括我們的 Observability 服務,本篇將介紹幾個和 Observability Signals 儲存有關的議題。
隨著 Observability 工具觀測的服務越來越多,再加上時間的累積,儲存空間的需求也會隨之增加。因此我們需要考慮如何確保儲存空間不會被用盡,並同時盡可能保存足夠時間範圍的資料。若沒有良好的設計與規劃,除了成本的浪費、維運的負擔外,甚至會發生像前面提到的停機事故。
雖然就 Observability 的角度來看,我們傾向於保存盡量多的資料以供後續查詢。然而,有些資料其實根本就不會被使用,不僅占用了儲存空間,也會對查詢的效率造成影響。因此,需要判斷哪些資料是真正有用,而哪些資料是可以捨棄的。
針對 Metrics 我們可以透過僅保留合適的 Label 來縮減儲存的資料量,或者是直接排除無人使用的 Metrics。例如,選擇只保存 http_requests_total{method="GET", path="/api/v1/users"}
,而不是 http_requests_total{method="GET", path="/api/v1/users", user_agent="Chrome", user_agent_version="117.0.5938.149"}
。因為後者額外儲存的 Label 會導致資料量過大,而且也不太可能會有人去查詢使用者瀏覽器的細節,透過這樣的方式能夠有效降低 Metrics 的儲存空間。
Grafana Labs 在今年五月撰寫了一篇文章分享他們在 Grafana Cloud 上提供的 Adaptive Metrics 新功能。該功能透過分析將 Metrics 劃分為三類:未使用、只使用部分 Label、使用全部 Label 三種類型,並對未使用的 Metrics 進行移除,同時對只使用部分 Label 的 Metrics 進行 Label 縮減或合併。實測結果顯示,這能讓參與測試的 150 家客戶平均節省 20% ~ 50% 的儲存空間。
對於 Traces,常見的作法是透過 Sampling 採樣降低收集的 Trace 數量。例如,Jaeger 支援多種 Head Sampling 採樣策略,OpenTelemetry Collector 則提供同時提供 Head Sampling 與 Tail Sampling。不過 Sampling 雖能有效減少儲存空間,但也可能導致 Traces 資料不完整。
另一種節省空間的方法是在資料收集階段就篩選特定的 Span。例如,某些 Trace 或 Span 本身就沒有太多價值,像一些不重要的 HTTP Request,如 /health
或是 /metrics
,但可能因為都是透過 OpenTelemetry 的 Automatic Instrumentation 產生,也沒以辦法在生成階段就進行排除,導致大量無用的資料被收集。透過 OpenTelemetry Collector 的 Filter Processor ,在收集階段就能排除這些 Span,進一步減少儲存需求。
左右兩側為同一筆 Trace,但右側的 Trace 已經透過 Filter Processor 移除了不需要的 Span,因此儲存空間更小。
資料儲存期限是一個需要妥善評估的議題。由於儲存空間有限,如果不加以管控,可能會耗盡所有空間。同時,資料保存期限也不能過短,因可能需較長時間才能發現某些問題。例如,一個服務的效能可能會逐漸下降,但這種變化是漸進式的,因此可能需要長時間才會被察覺。在這樣的前提下,目標是在有限的儲存空間裡,保存足夠長的時間範圍的資料。
負責資料儲存的各類服務通常會提供 Retention 的設定選項,能夠設定保留多少時間長度的資料。官方文件都會有特別的說明,如 Loki 的 Retention、Mimir 的 Retention、Tempo 的 compactor.block_retention 設定等。但因為這些機制都是基於時間作為保留條件,所以還是需要留意儲存空間的使用情況,持續監控和評估儲存空間是否足以應對資料量的成長。特別是當突然有大量資料進來,或者是隨著使用者增多而造成每日資料量持續增加,都有可能會導致儲存空間瞬間用盡。
儲存方式對成本影響甚鉅,例如儲存在 Object Storage 的成本就會比儲存在 Block Storage 便宜。以 Google Cloud Platform 為例,Object Storage 類型的 Cloud Storage 的價格在其最貴的等級是每月 0.020 USD/GB(2023/09/21 asia-east1 Standard Storage 價格),而 Block Storage 類型的永久磁碟的最便宜價格則是每月 0.040 USD/GB(2023/09/21 asia-east1 Standard provisioned space 價格),價格相差達一倍。除此之外,多數工具都提供資料壓縮功能,這也能顯著減少所需的儲存空間。
在討論儲存方式時,多租戶(Multi-tenancy)的議題也不容忽視。特別是當一個工具或平台被多個不同的使用者或組織使用時,確保各方資料的隔離性變得尤為重要,以防不同使用者不經意間讀取到他人資料。例如,Loki、Mimir 和 Tempo 都提供多租戶功能,只需透過設定 Tenant ID 便可實現資料隔離。在實際儲存資料時,例如使用可自建的相容於 S3 格式的 MinIO,資料會被儲存在獨立的 Bucket 中以實現隔離。
範例程式碼:29-long-term-storage
啟動所有服務
docker-compose up -d
檢視服務
minio/supersecret
admin/admin
使用 k6 發送 Request
k6 run --vus 1 --duration 300s k6-script.js
使用 Explore 檢視 Tempo、Loki、Mimir 資料
關閉所有服務
docker-compose down
啟動所有服務
docker-compose -f docker-compose.otel.yaml up -d
檢視服務
admin/admin
關閉所有服務
docker-compose -f docker-compose.otel.yaml down
/metrics
endpointtraces/tempo-1
:接收 Traces 資料,只進行 Batch 後輸出至 Tempo-1traces/tempo-2
:接收 Traces 資料,進行 Batch 和 Filter 排除 attribute http.method
為空的 Span,之後輸出至 Tempo-2在資料儲存的議題中,成本和效益的平衡總是一個棘手的問題,當然不可能像是標題所說的一樣保存一萬年。選擇更便宜的儲存方式或利用資料壓縮技術能減緩成本壓力,但由於儲存空間有限,還是需要審慎評估資料的重要性和保存期限。並隨時監控與評估儲存空間的使用情況,以便即時調整儲存策略。