在分散式系統當道的今天,系統複雜度幾乎不可避免地持續膨脹。面對越來越難以除錯的架構,許多工程團隊開始認真考慮一個問題:到底該不該拋開 Datadog、Splunk 這類 SaaS 供應商,自己動手建一套可觀測性(Observability,指透過指標、日誌、追蹤等遙測資料理解系統內部狀態的能力)平台?在 QCon London 2026 的演講中,來自 DuckDuckGo 的 SRE Colin Douch 給出了一個看似矛盾、實則務實的答案:能不自己架就不要自己架,但當你真的走到那一步,有些代價與選型原則必須先想清楚。
Douch 的經歷橫跨多個大規模系統環境:他曾在 Cloudflare 創建並共同領導可觀測性團隊,是 Xero 的 SRE 團隊創始成員,更早之前還在礦業領域做過監控工作,目前則在 DuckDuckGo 負責維運全球搜尋與 AI 查詢系統。正因為看過太多團隊在自架路上摔跤,他開場就直言,多數工程師應該竭盡全力壓抑「自己架一套」的衝動。Datadog 或 Splunk 的帳單確實驚人,但自己維護一套觀測系統意味著至少要投入兩到三名工程師、遠超預期的時間與金錢,以及無止盡地泡在 GitHub Issue 裡。不過他也承認,總有一天你會被迫走向自架:遙測資料量成長到供應商帳單失控、稽核單位質疑為何把大量資料送給第三方、或 BI 團隊需要供應商不願做的功能。到了那個時刻,以下這些實戰經驗就派得上用場。
自架觀測平台的傳統樣貌是所謂「三支柱」:metrics(指標)、logs(日誌)、traces(分散式追蹤),但真正的難點不在儲存資料,而在如何把這三種資料串起來互相跳轉。先看指標這一層。大多數人直覺會選 Prometheus,研究較深的人則會推薦 VictoriaMetrics。Douch 坦言,純就時序資料庫的效率、擴展性與維運容易度而言,VictoriaMetrics 確實更好,但他仍然建議選 Prometheus,關鍵在於一個名為 exemplars(範例)的功能:它允許在指標上附加一組可變動的標籤,例如當錯誤指標突然飆升時,把觸發該次飆升的請求之 trace ID 附上去。有了這個連結,就能在 Grafana 圖表上一鍵從「指標異常」跳到「告訴你為什麼異常的追蹤資料」,這正是自架環境中最難補上的跨資料類型橋接。Prometheus 的弱點是幾乎無法水平擴展:它把最近兩小時的資料緩存在記憶體中(稱為 head chunk),Cloudflare 的經驗是每個活躍時間序列約占 4 KB,可直接用於容量規劃。當規模超出單機,就需要長期儲存方案:Mimir 和 Cortex 透過 remote write 直接寫入物件儲存,繞開 head chunk 限制;Thanos 則依賴每個 Prometheus 旁的 sidecar 上傳資料區塊,其分散式查詢引擎能把運算下推到 sidecar 再合併結果,適合跨多個資料中心的架構;此外 Thanos 正在實驗的 Parquet 儲存引擎,效能基準已接近 VictoriaMetrics,值得關注。
日誌是另一個容易做錯的地方。純文字日誌搭配全文檢索(例如傳統 Elasticsearch 用法)在精確查詢時問題重重:搜尋「user 20」會連 user 202、user 2070 一起撈出來,加上錨點又會因各呼叫點格式不一致而破功。解法是結構化日誌,而結構化日誌的成敗其實取決於儲存引擎能否對結構化欄位建立索引,且最好支援動態 schema——因為觀測的本質就是「我們不知道自己不知道什麼」,事先定死要索引哪些欄位行不通。Elasticsearch 的動態欄位上限一旦觸頂,攝入直接停止,調高上限又會拖垮效能;Grafana 的 Loki 採用串流標籤模型,但只有在攝入時聲明的欄位才會被索引,其餘又退回全文檢索,等於要求你預先知道要搜什麼。Douch 的推薦是 VictoriaLogs,它和 VictoriaMetrics 一樣是完整的欄式資料庫,天然支援動態索引。直接寫進 ClickHouse 用 SQL 查詢也是選項,但維運成本高,Cloudflare 是靠一支專職 ClickHouse 團隊才撐得起來。在日誌的使用面上,他特別推廣 canonical logging(規範化日誌,概念源自 Stripe):與其在程式各處零散地印日誌,不如在處理過程中把所有欄位收進 context 區塊,最後一次性輸出一筆完整事件。每個工作區塊一行日誌,再附上 correlation ID,除錯時就不用在多條日誌流之間來回拼湊。
追蹤則是複雜度最高的一層。Douch 半開玩笑地說,追蹤本質上就是「加了結構的日誌」:給結構化日誌加一個 span ID、一個代表整個請求的 trace ID、一個 parent span ID,依 trace ID 聚合起來就是一條 trace。它真正的價值在於父子關係明確建模了「哪個函式呼叫了哪個函式」的因果鏈,不用像日誌那樣仰賴不可靠的時間排序——畢竟電腦上的時間會飄移甚至倒退。工具面上,OpenTelemetry(OTel,一套統一遙測格式與 SDK 的規範)已是追蹤埋點的實質唯一選擇,Jaeger 與 Zipkin 等舊方案皆已或正在被其取代;但他建議 OTel 的指標與日誌規範暫時不要用,以免徒增複雜度。後端儲存的選擇在 Jaeger 與 Grafana Tempo 之間:Tempo 功能更強,TraceQL 查詢強大,還能從 trace 生成指標,但自帶儲存引擎在每秒數萬條 trace 以上就撐不住;Jaeger 儲存層無關,可從 Elasticsearch 起步、需要時升級到 ClickHouse,擴展路徑更好,這也是 Cloudflare 選它的原因——代價是得自行維護私有 fork 補齊缺失功能,他認為「缺乏功能完整且可擴展的追蹤系統」正是開源觀測生態最大的缺口。此外,資料量一大就必須談採樣:head sampling 是在進入時以機率決定保留與否,簡單但有個陷阱——只保留 10% 的資料時,所有統計都要乘以十,且比例一改歷史倍率就跟著變;他的建議是把採樣率嵌進 span 裡,讓查詢時引擎自動處理。tail sampling 則是對錯誤請求與成功請求套用不同採樣率,需要緩衝整條 trace 等所有 span 到齊才能判斷,涉及緩衝時長、分散式分片等難題,除非已遇到 head sampling 解決不了的問題,否則不建議。採樣等處理邏輯需要有地方執行,也就是遙測管線:選項包括 OTel Collector(Go 寫成)、基於它的 Grafana Alloy,以及 Rust 寫的 Vector(已被 Datadog 收購)。身為 OTel Collector 的貢獻者,Douch 直言該專案受 CNCF 流程與無償志工限制,小改動也可能拖上數週,急用就得內部 fork 自行建置。
最後一塊拼圖是把一切串起來的 UI。Grafana 幾乎是唯一主流選項,但它的許多實用功能——儀表板使用追蹤、完善的資料源權限——都被鎖在付費牆後,開源社群的貢獻也會被擋下,導致自架用戶常累積出數千個不敢刪的儀表板。他推薦關注 CNCF 的 Perses 專案,它免費提供這些功能,還支援自動化儀表板與「臨時儀表板」:可在一段時間後自動刪除,甚至能由告警工具透過 webhook 自動建立。他也建議把儀表板分成兩類標籤管理:BI 類(業務指標、SLO,長期穩定)與除錯類(針對特定故障模式的鑽研,問題解決後就該清理)。當指標帶 exemplars、日誌帶 canonical context、trace 貫穿全域,一套典型的除錯流程就成型了:告警觸發、從指標的 exemplar 點進 trace、看到是哪個服務出問題、再透過每個 span 對應的 canonical log 一行,直接定位失敗的具體原因。
展望未來,Douch 認為三支柱並不會消失,而是會被「推上堆疊」:日誌其實是 trace 的子集,指標只是對它們的計數與聚合,如果埋點時的高上下文寬事件(wide event)夠完整,其他遙測資料其實可以在觀測工具端合成出來,應用程式只需埋點一次。SigNoz 這類一體化方案已有初步嘗試,OTel Collector 的 connector 與 Vector 的 log-to-metric 也朝此方向發展。演講後的問答中,他對 AI 在觀測領域的應用也持保留態度:目前把 trace 丟進 AI 代理的 context window 後往往很快燒完,中間仍需要一層資訊蒸餾機制。總結他的核心觀點:資料本身不等於可觀測性,就像堆滿未標記箱子倉庫不算圖書館;自架是一條可行但昂貴的路,能靠供應商解決就用錢解決,真的要自架,就把每一層的取捨想透徹,並盡可能讓三種遙測資料在同一個除錯畫布上流動。
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。