捕獲和增強原生系統的可觀測性來發現錯誤

2021-09-11 13:13:13 字數 4109 閱讀 3997

在對 tidb 進行 chaos 實踐的時候,我一直在思考如何更好的發現 tidb 整個系統的故障。最開始,我們參考的就是chaos engineering裡面的方式,觀察系統的穩定狀態,注入乙個錯誤,然後看 metrics 上面有啥異常,這樣等實際環境**現類似的 metrics,我們就知道發現了什麼故障。

但這套機制其實依賴於如何去注入錯誤,雖然現在我們已經有了很多種錯誤注入的方式,但總有一些實際的情況我們沒有料到。所以後來我們又考慮了另外的一種方式,也就是直接對 metrics 歷史進行學習,如果某一段時間 metrics 出現了不正常的波動,那麼我們就能報警。但這個對我們現階段來說難度還是有點大,只使用了幾種策略,對 qps,latency 這些進行了學習,並不能很好的定位到具體出了什麼樣的問題。

所以我一直在思考如何更好的去發現系統的故障。最近,剛好看到了 osdi 2018 一篇 *****,capturing and enhancing in situ system observability for failure detection,眼睛一亮,覺得這種方式也是可以來實踐的。

大家都知道,在生產環境中,故障是無處不在,隨時可能發生的,譬如硬體問題,軟體自身的 bug,或者運維使用了乙個錯誤的配置這些。雖然多數時候,我們的系統都做了容錯保護,但我們還是需要能盡快的發現故障,才好進行故障轉移。

但現實世界並沒有那麼美好,很多時候,故障並不是很明顯的,譬如整個程序掛掉,機器壞掉這些,它們處於一種時好時壞的狀態,我們通常稱為「gray failure」,譬如磁碟變慢了,網路時不時丟包。這些故障都非常隱蔽,很難被發現。如果單純的依賴外部的工具,其實很難檢測出來。

上面是作者舉的乙個 zookeeper 的例子,client 已經完全不能跟 leader 進行互動了,但是 leader 卻仍然能夠給 follower 傳送心跳,同時也能響應外面 monitor 發過來的探活命令。

如果從外面的 monitor 看來,這個 zookeeper 集群還是正常的,但其實它已經有故障了。而這個故障其實 client 是知道的,所以故障檢測的原理很簡單,從發起請求的這一端來觀察,如果發現有問題,那就是有故障了。而這也是這篇**的中心思想。

在**裡面,作者認為,任何嚴重的 gray failure 都是能夠被觀察到的,如果發起請求的這邊遇到了錯誤,自然下一件事情就是將這個錯誤給匯報出去,這樣我們就知道某個地方出現了故障。於是作者開發了 panorama 這套系統,來對故障進行檢測。

先來說說 panorama 一些專業術語。

panorama 整體結構如下:

panorama 通過一些方式,譬如靜態分析**進行**注入等,將 observer 跟要觀察的 subject 進行繫結,observer 會將 subject 的一些資訊記錄並且匯報給本地的乙個 local observation store(los)。本地乙個決策引擎就會分析 los 裡面的資料來判斷這個元件的狀態。如果多個 los 裡面都有對某個 subject 的 observation,那麼 los 會相互交換,用來讓**的 verdict 更好的去判斷這個 component 的狀態。

而用來判斷乙個 component 是不是有故障也比較容易,採用的是一種大多數 bounded-look-back 演算法。對於乙個 subject,它可能會有很多 observations,首先我們會對這些 observations 按照 observer 進行分組,對每組單獨進行分析。在每個組裡面,observations 會按照時間從後往前檢查,並且按照 context 進行聚合。如果乙個被觀察的 observation 的 status 跟記錄前面相同 context 的 observation status 狀態不一樣,就繼續 loop-back,直到遇到乙個新的 status。對於乙個 context,如果最後的狀態是 unhealthy 或者 healthy 的狀態沒有達到多數,就會被認為是 unhealthy 的。

通過這種方式,我們在每組裡面得到了每個 context 的狀態,然後又會在多個組裡面進行決策,也就是最常用的大多數原則,哪個狀態最多,那麼這個 context 對應的狀態就是哪乙個。這裡我們需要額外處理下 pending 這個狀態,如果當前狀態是 healthy 而之前老的狀態是 pending,那麼 pending 就會變成 healthy,而如果一直是 pending 狀態並超過了某個閾值,就會退化成 unhealthy。

這裡再來說說 observability 的模式。對於分布式系統來說,不同 component 之間的互動並不是同步的,我們會面臨如下幾種情況:

如果兩個元件 c1 和 c2 是同步互動,那麼當 c1 給 c2 傳送請求,我們就完全能在 c1 這一端知道這次請求成功還是失敗了,但是對於非同步的情況,我們可能面臨乙個問題,就是 c1 給 c2 發了請求,但其實這個請求是放到了非同步訊息佇列裡面,但 c1 覺得是成功了,可是後面的非同步佇列卻失敗了。所以 panorama 需要有機制能正確處理上面多種情況。

為了能更好的從 component 上面得到有用的 observations,panorama 會用乙個離線工具對**進行靜態分析,發現一些關鍵的地方,注入鉤子,這樣就能去匯報 observations 了。

通常執行時錯誤是非常有用的能證明有故障的證據,但是,並不是所有的錯誤都需要匯報,panorama 僅僅會關係跨 component 邊界產生的錯誤,因為這也是通過發起請求端能觀察到的。panorama 對於這種跨域的函式呼叫稱為 observation boundaries。對於 panorama 來說,第一件事情就是定位 observation boundaries。通常有兩種 boundaries,程序間互動和執行緒間互動。程序間互動通常就是 socket i/o,rpc,而執行緒間則是在乙個程序裡面跨越執行緒的呼叫。這些 panorama 都需要分析出來。

當定位了 observation boundaries 之後,下一件事情就是確定 observer 和 subject 的標識。譬如對於程序間互動的 boundaries,observer 的標識就可能是這個程序在系統裡面的唯一標識,而對於 subject,我們可以用 method 名字,或者是函式的乙個引數,類裡面的乙個欄位來標識。

然後我們需要去確定 observation points,也就是觀測點。通常這些點就是**處理異常的地方,另外可能就是一些正常處理返回結果但會對外報錯的地方。

上面就是乙個簡單分析**得到 observation points 的例子,但這個仍然是同步的,對於 indirection 的,還需要額外處理。

對於非同步請求,我們知道,通過發出去之後,會非同步的處理結果,所以這裡分為了兩步,叫做 ob-origin 和 ob-sink。如下:

對於 ob-origin,**分析的時候會先給這個 observation 設定成 pending 狀態,只有對應的 ob-sink 呼叫並且返回了正確的結果,才會設定成 healthy。因為 ob-origin 和 ob-sink 是非同步的,所以**分析的時候會加上乙個特殊的字段,包含 subject 的標識和 context,這樣就能讓 ob-origin 和 ob-sink 對應起來。

上面大概介紹了 panorama 的架構以及一些關鍵的知識點是如何實現的,簡單來說,就是在一些關鍵**路徑上面注入 hook,然後通過 hook 對外將相關的狀態給匯報出去,在外面會有其他的分析程式對拿到的資料進行分析從而判定系統是否在正常工作。它其實跟加 metrics 很像,但 metrics 只能看出**出現了問題,對於想更細緻定位具體的某乙個問題以及它的上下文環境,倒不是特別的方便。這點來說 panorama 的價值還是挺大的。

panorama 的**已經開源,總的來說還是挺簡單的,但我沒找到核心的**分析,注入 hook 這些,有點遺憾。但理解了大概原理,其實先強制在**寫死也未嘗不可。另乙個比較可行的辦法就是進行在**裡面把日誌新增詳細,這樣就不用**注入了,而是在外面寫乙個程式來分析日誌,其實 panorama **裡面提供了日誌分析的功能,為 zookeeper 來設計的,但作者自己也說到,分析日誌的效果比不上直接在**裡面進行注入。

那對我們來說,有啥可以參考的呢?首先當然是這一套故障檢查的理念,既然 panorama 已經做出來並且能發現故障量,自然我們也可以在 tidb 裡面實施。因為我們已經有在 go 和 rust **裡面使用 fail 來進行錯誤注入的經驗,所以早期手寫監控**也未嘗不可,但也可以直接完善日誌,提供乙個程式來分析日誌就成。如果你對這塊感興趣,想把 panorama 相關的東西應用到 tidb 中來,歡迎聯絡我 [email protected]

函式計算的可觀測性

作者 夏莞 阿里巴巴函式計算團隊 本文整理自 serverless 技術公開課 可觀測性是什麼呢?維基百科中這樣說 可觀測性是通過外部表現判斷系統內部狀態的衡量方式。在應用開發中,可觀測性幫助我們判斷系統內部的健康狀況。在系統出現問題時,幫助我們定位問題 排查問題 分析問題 在系統平穩執行時,幫助我...

構建可觀測的分布式系統

如今的系統正在變得越來越複雜 微服務在網路上是分布式存在的,並且能夠動態擴充套件,這樣會導致各種形式的故障,出現故障的方式是我們無法預料的。如果盲目相信我們能夠構建完美的系統將會形成錯誤的安全感,所以我們需要預先為此做好充分地準備。在可觀測方面進行投資能夠讓我們掌握系統的執行狀況,這些事情是我們以前...

O11ycon會議討論了可觀察性的收益和挑戰

第一次o11ycon會議對軟體和系統中日漸興起的可觀察性概念進行了全面地介紹,可觀察性能夠幫助人們掌握系統是否在按照預期執行,並且有助於診斷問題和確定解決方案。u0026 xd n u0026 xd n honeycomb提供乙個用於實時系統除錯和可觀察性的平台,該公司的ceo charity ma...