淺談Observability
Observability的歷史
(又在講古了XD) Observability這詞, 最早在控制理論出現, 這是一門關注如何控制動態系統的工程學科, 其中的Rudolf E. Kálmán在1960的論文中提出的.
Observability to describe mathematical control systems. In control theory, observability is defined as a measure of how well internal states of a system can be inferred from knowledge of its external outputs.
恩...大概就根據一個系統的外部輸出的資訊來推斷內部狀態的能力,甚至可以透過輸出的資訊搭配知識來做出推斷假設與證明. 進而優化再持續性的觀測, 是不能稱為系統具備可觀測性的, 因為這樣子組織會高度依賴少部份人的能力而帶來管理風險.
這也呼應了DevOps的8字環.
Kálmán後來有把這論文的理論, 用在軟體系統上, 並且給出了更詳細的要求, 只有滿足了才可稱為具備Observability.
了解應用程式的內部運作
了解你的應用程式可以進入任何的系統狀態, 甚至你以前都沒見過也無法預測的新狀態
僅透過觀察與存取外部工具來了解軟體的內部運作與系統狀態
了解內部狀態, 不需要提供任何新的自定義程式來處理解析它.
Observability Engineering這本書的第一章, 有提出很多小問題來詢問自己是否夠了解自己的系統. 我隨便舉兩三題 1.是否曾經遇過線上問題, 自己都能解釋異常狀況, 沒碰到過排查的死胡同, 最後只能靠通靈跟重開機. 2.如果有用戶抱怨系統很慢, 但你的監控面板顯示99th, 99.9th甚至99.99th的請求都很快, 能找到隱藏的超時嘛?
之類的很多問題XD
1988年, SNMPv1定義在RFC1157, 其中提到了大家很熟悉的Monitoring. 其中有Metric度量指標,它是一個數字, 跟隨著一些tag, 我們就能用這些tag對這些metrics的數字做一些分類和搜尋. 通常這些metric指標都是一次性產生、廉價的存儲空間. 但它們又通常會用Time-Series bucket(時間序列集合)來聚合存放. 現在有很多複雜的應用或組織運作都建立在Metric指標上, 像是Time-Series databases(TSDBs)、一些統計分析、圖形儀表板、運維團隊、On-Call輪轉等等的, 很多方式能展示跟告知團隊. 但這些總有上限, 這上限在這些metric指標都是自己對系統已知的資訊. 平常跑得很正常的系統, 突然壞了, metric指標也不出來時, 大部分的運維團隊就會用low-level的指令來查找問題, 像是strace, tcpdump等等數百條命令來嘗試讓主機來回答問題.
且現在的系統架構往往是
一個應用系統有多組服務來支撐, 換言之系統很複雜
有很多種的持久化服務(像是DB, storage systems)
Infrastructure是很動態地, 像容量就任意的伸縮
許多服務是我們有依賴, 但不歸屬我們做管理控制
分散式系統是難以被完整預測的
還有很多原因, 將導致團隊在治理跟排查上遭遇很大的困難. 若是沒有一個高維度(Dimensionality)和高基數(Cardinality)資料, 貫穿在眾多線索中, 將會非常難在現在這樣複雜的系統架構裡快速地找到問題, 甚至證明假設.
基數Cardinality
在關聯式資料庫裡, Cardinality指的是資料的唯一性. Low-cardinality表示一列有很多重複的值. 性別/姓名都算是低基數. High-cardinality意味著該列包含很大比例的唯一值. 所以像UniqueID, UUID這樣的值在該列則能稱為高基數.
Cardinality對於Observability是非常重要的, 因為高基數的資料在Debug或了解系統的資料識別上是最有用有效的. 像是UserIDs, ShoppingCartIDs, RequestIDs其他等等的高基數ID. 又或是我們之後要介紹的TraceIDs, SpanIDs, 或是容器ID, 主機名稱都是查詢唯一ID的好方法. 高基數資料的好處除了方便識別外, 也能轉化成低基數的資料, 像是分類分堆, 資料前綴/後綴等等的; 但低基數的資料卻不能反過來轉化成高基數的資料.
但是!! 大部分基於Metrics的工具或服務(像Prometheus), 基本都是處理低基數的資料. 通常低基數的資料都是要是前先決定好的. 但通常很多人事先不太清楚哪些指標做度量的, 或哪些標籤是需要做識別.
維度Dimensionality
基數講的是資料的唯一性. 維度講的是該資料所擁有key(屬性)的數量. 在Observability System中, Telemetry(遙測)數據是由任意寬度(Wide)的結構化事件所生成的. 這些事件能被稱為Wide, 是因為它們可以包含上百甚至上千個Key-value pair(或者叫維度Dimensionality).
圖上的P是特徵, n則是metric資料. 盡可能描述多點特徵. 統計學對於高維度資料有嚴格的定義[^1].
像之後要介紹的Prometheus, 其metric資料裡面能含有任意數量的k-v pairs; 結構化Log其內容也是有很多k-v pair來描述其上下文的資訊, 便於觀察了解系統.
上下文Context
所有的Signal(之後會解釋), 都有相同的內容. 其實就是在空間上建立資料之間的關聯.
舉例, Prometheus[^2]首頁就有這段描述
Prometheus就是實現能提供一個高維度資料的模型, 其中也包含了一組任意數量的k-v pair.
在現在這年代, 硬碟容量是很方便被擴充的, 且讀寫速度也遠快於以前. 沒必要省成這樣. 多冗餘些資訊在資料內反而方便之後關聯查詢用. 數據的維度越高, 就越有可能找到系統行為中隱藏或難以捉摸的模式(還是交給數據分析專家幫忙分析好了).
假設我們定義了6個高基數維度的事件, time, app, host, user, endpoint還有status. 我們就可以建立查詢方法來分析這些維度的組合和顯示相關性. 像是可以搜尋所有status是502, time發生在過去半小時內的, 且host是ithome的數據. 或是找所有status是403, 由user是Nathan對著ironman14th這endpoint發生的錯誤, 等等的.
今日小總結
Observability相關的工具或服務, 其實不只是上面提到的metrics, 或者是限制遙測資料的基數跟維度. 反而是鼓勵開發團隊為每個可能發生的事件收集豐富的遙測資訊. 將請求的完整上下文也存儲起來, 在某些時候使用或者分析用.
聊到現在, 感覺上Observability就只是Monitoring換了一層包裝的講法, 但不管如何, Observability都是為了給系統帶來更好的Visibility(可見性), 易於Debugging調試, 是一個穩定的系統在維護與發展上的基石.
明天也會繼續講更多Observability. 謝謝各位與隊友們.
參考資料
[^1]: What is High Dimensional Data? [^2]: Prometheus Observability Whitepaper