談談 Kubernetes list-watch 的設計原理

kubernetes 的設計裏面大致上分爲 3 部分:

而正因爲這些設計特性,才使得 kubernetes 工作非常穩定。

Level Trigger 與 Edge trigger

看到網上有資料是這麼解釋兩個屬於的:

通過查詢了一些資料,實際上也不明白這些究竟屬於哪門科學中的理論,但是具體解釋起來看得很明白。

LEVEL TRIGGERING:電流有兩個級別,VHVL。代表了兩個觸發事件的級別。如果將 VH 設置爲 LED 在正時鐘。當電壓爲 VH 時,LED 可以在該時間線任何時刻點亮。這稱爲 LEVEL TRIGGERING,每當遇到 VH 時間線就會觸發事件。事件是在時間內的任何時刻開始,直到滿足條件。

Edge TRIGGERING: 如圖所示,會看到上升線與下降線,當事件在上升 / 下降邊緣觸發時(兩個狀態的交點),稱爲邊緣觸發(Edge TRIGGERING)。

如果需要打開 LED 燈,則當時鍾從 VL 轉換到 VH 時纔會亮起,而不是一家處在對應的時鐘線上,僅僅是在過渡時亮起。

爲什麼 kubernetes 使用 Level Trigger 而不使用 Edge trigger

如圖所述,兩種不同的設計模式,隨着時間形狀進行響應,當系統在由高轉低,或由低轉高時,系統處在關閉或者不可控的異常狀態下,應如何觸發對應的事件呢。

換一種方式來來解釋,比如說通過 加法運算,如下,i=3,當給 I+4 作爲一個操作觸發事件。

# let i=3
# let i+=4
# let i
# echo $i
7

當爲 Edge trigger 時操作的情況下,將看到 i+4 , 而在 level trigger 時看到的是 i=7。這裏將會從 ``i+4` 一直到下一個信號的觸發。

信號的干擾

通常情況下,兩者是沒有區別的,但在大規模分佈式網絡環境中,有很多因素的影響下,任何都是不可靠的,在這種情況下會改變了我們對事件信號的感知。

如圖所示,圖爲 Level TriggerEdge trigger 的信號發生模擬,在理想情況下,兩者間並沒有什麼不同。

一次中斷場景

由圖可知,Edge trigger 當在恰當的時間點發生信號中斷,會對整個流產生很大的影響,甚至改變了整個狀態,對於較少的干擾並不會對有更好的結果,而單次的中斷,使 Edge trigger 錯過了從高到低的變化,而 level trigger 基本上保證了整個信號量的所有改變狀態。

兩次中斷的場景下

由圖可看到,信號的上升和下降中如果存在了中斷,Edge trigger 丟失了上升的信號,但最終狀態是正確的。

在信號狀態的兩次變化時發生了兩次中斷,Level TriggerEdge trigger 之間的區別很明顯,Edge trigger 的信號錯過了第一次上升,而 Level Trigger 保持了最後觀察到的狀態,直到拿到了其他狀態,這種模式保證了得到的信號基本的正確性,但是發生延遲到中斷恢復後。

通過運算來表示兩種模式的變化情況

完整的信號

# let i=2

# let i+1
# let i-=1
# let i+1

# echo $i
3

Edge trigger

# let i=2

# let i+1  
(# let i-=1) miss this
# let i+1

# echo $i
4

如何使理想狀態和實際狀態一樣呢?

在 Kubernetes 中,不僅僅是觀察對象的一個信號,還觀察了其他兩個信號,集羣的期待狀態與實際狀態,期望的狀態是用戶期望集羣所處的狀態,如我運行了 2 個實例(pod)。在最理想的場景下,集羣的實際狀態與期待狀態是相同的,但這個過程會受到任意的外界因素干擾被影響下,實際狀態與理想狀態發生偏差。

Kubernetes 必須接受實際狀態,並將其與所需狀態調和。不斷地這樣做,採取兩種狀態,確定其之間的差異,並糾正其不斷更改,以使實際狀態達到理想狀態。

如圖所示,在一個 Edge trigger 中,最終的結果很可能會與理想中的結果發生偏差。

當初始實例爲 1 時,並希望擴展爲 5 個副本,然後再向下縮容到 2 個副本,則 Edge trigger 環境下將看到以下狀態:系統的實際狀態不能立即對這些命令作出反應。正如圖所述,當只有 3 個副本在運行時,它可能會終止 3 個副本。這就給我們留下了 0 個副本,而不是所需的 2 個副本。

# let replicas=1
# let replicas += 4 # 此時副本數爲5,但是這個過程需要時間而不是立即完成至理想狀態
# let replicas -= 3 # 當未完成時又接到信號的變化,此時副本數爲3,減去3,很可能實際狀態爲0,與理想狀態2發生了偏差

而使用 Level Trigger 時,會總是比較完整的期望狀態和實際狀態,直到實際狀態與期望狀態相同。這大大減少了狀態同步間(錯誤)的產生。

總結

每一種觸發器的產生一定有其道理,Edge trigger 本身並不是很差,只是應用場景的不同,而使用的模式也不同,比如 nginx 的高性能就是使用了 Edge trigger 模型,如 nginx 使用了 Level trigger 在大併發下,當發生了變更信號等待返回時,發生大量客戶端連接在偵聽隊列,而 Edge trigger 模型則不會出現這種情況。

綜上所述,kubernetes 在設計時,各個組件需要感知數據的最終理想狀態,無需擔心錯過數據變化的過程。而設計 kubernentes 系統消息通知機制(或數據實時通知機制),也應滿足以下要求:

正是因爲 Kubernetes 使用了 Level trigger 才讓集羣更加可靠。

參考資料

原文鏈接:https://www.cnblogs.com/Cylon/p/15681121.html

k8s 技術圈 專注容器、專注 kubernetes 技術......

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/feR5XsWhNCGwM8ln_RsaKw