Envoy的執行緒模型 翻譯

2022-06-02 15:54:11 字數 2242 閱讀 9783

關於envoy **的底層文件相當稀少。為了解決這個問題我計畫編寫一系列文件來描述各個子系統的工作。由於是第一篇, 請讓我知道你希望其他主題覆蓋哪些內容。

乙個我所了解到最共同的技術問題是關於envoy使用的執行緒模型的底層描述,這篇文章將會描述envoy如何使用執行緒來處理連線的(how envoy maps connections to threads), 同事也會描述thread local storage(tls)系統是如何使內部**平行且高效的。

figure 1: threading overview

如同圖一所示,envoy使用了三中不同型別的執行緒。

如上所述, 所有worker執行緒都會監聽埠而沒有任何分片,因此,核心智慧型的分配accept的套接字給worker程序。現代核心一般都很擅長這一點,在開始使用其他監聽同一套接字的其他執行緒之前,核心使用io 優先順序提公升等特性來分配執行緒的工作,同樣的還有不適用spin-lock來如理所有請求。

一旦woker accept了乙個連線,那麼這個連線永遠不會離開這個worker(乙個連線只由同一worker進行處理), 所有關於連線的處理都將會在worker執行緒內進一步處理,包括任何**行為。這有一些重要的含義:

到目前為止,在討論主線程和worker執行緒時我們已經多次使用術語'non-blocking'.幾乎所有**都是假設沒有阻塞的情況下進行編寫。但是,這並非完全正確(**有完全正確的東西),envoy確實使用了一些process wide locks.

由於envoy將主線程的職責和worker執行緒的職責完全分開,需要在主線程完成複雜的處理同時使每個worker執行緒高度可用。本節將介紹envoy的高階執行緒本地儲存(tls)系統。在下一節中,我將描述如何使用它來處理集群管理。

如已經描述的那樣,主線程基本上處理envoy過程中的所有管理/控制平面功能。(控制平面在這裡有點過載,但在特使程式本身考慮並與工人做的**進行比較時,似乎是合適的)。主線程程序執行某些操作是一種常見模式,然後需要使用該工作的結果更新每個工作執行緒,並且工作執行緒不需要在每次訪問時獲取鎖定

envoy的tls系統工作如下:

雖然非常簡單,但它非常強大與唯讀副本更新鎖類似.(實質上,worker執行緒在工作時從不會看到插槽的資料發生任何改變, 變化只發生在event切換的時候[5]

), envoy用兩種不同的方式來使用它:

在本節中,我將描述tls如何用於集群管理。群集管理包括xds api處理和dns以及執行狀況檢查。

圖3顯示了涉及以下元件和步驟的總體流程:

集群管理器(cluster manager)在envoy中管理已知上游的集群,包括cds api, sds/eds api dns 和活躍的健康檢查。它負責建立每個上游主機最終一致的檢視,上游主機包括了發現的主機和健康統計。

健康檢查器(health checker)進行活躍健康檢查,並將健康檢查的統計結果返回給集群管理器(cluster manager).

cds/sds/eds/dns 用來決定集群的成員,一旦狀態改變會返回給集群管理器(cluster manager).

每個worker 執行緒包含乙個 event loop。

當集群管理器要改變集群的狀態時,它將建立乙個集群狀態唯讀的快照(snapshot), 並將它傳送給每乙個worker 執行緒。

在下乙個靜止期中,worker執行緒將更新存在tls中的快照

在io事件需要確定主機如何負載均衡時,負載均衡器(load banlancer)將會查詢tls中存有的集群狀態資訊,這個過程中是無鎖的。(tls也可以觸發事件使得負載均衡器和其他元件重新計算快取記憶體和資料結構。但這超出了本文的範圍)

通過這些過程,envoy能夠處理每個請求而不使用任何鎖。除了tls**本身的複雜度之外,大部分**無需理解執行緒是如何具體工作的,使用單執行緒的方式即可。這使得大部分**易於修改且效能較好。

tls和rcu(read-copy update[6]

)在envoy內廣泛使用。

其他一些例子包括:

還有其他情況,但前面的例子應該已經足夠闡釋tls在envoy中的作用。

雖然envoy整體表現相當不錯,但是當它以非常高的併發和高吞吐使用時,有一些已知的點需要注意:

envoy的執行緒模型旨在簡化程式設計和提高效能,但如果設定不當,可能會浪費記憶體和連線使用。envoy的執行緒模型允許它在非常高的worker數量和高吞吐量下表現良好。

原文 in-memory buffer ↩︎

central "stat store" ↩︎

thread local storage(tls) ↩︎

原文 slot ↩︎

可以檢視ibm對rcu的介紹

↩︎

Redis的執行緒模型

redis是單執行緒。採用單執行緒理由是 1 redis 完全是基於記憶體的操作,cpu 不是 redis 的瓶頸,其瓶頸最有可能是機器記憶體的大小或者網路頻寬。2 單執行緒容易實現 好處是採用單執行緒,避免了不必要的上下文切換和競爭條件,不存在多執行緒導致的 cpu 切換,不用去考慮各種鎖的問題,...

程序與執行緒 翻譯文

所有的內容均來自 在我們開始討論執行緒,程序,時間片以及各種神奇的 排程機制 之前,先來建立乙個模擬。我首先要做的就是說明執行緒和程序是如何工作的。我能想到的最好的方式 不涉及實時系統的設計 就是把執行緒和程序想象成一些實際的情形。程序就像是乙個房子 讓我們用乙個常規的 日常的物品來模擬程序和執行緒...

執行緒模型 讀寫模型(1)

讀寫模型 讀寫模型是乙個稍微複雜一些的模型。乙份共享資源允許多個讀者同時讀取。但是只要有乙個寫者在寫這份共享資源,任何其他的讀者和寫者都不能訪問這份共享資源。讀寫模型實現起來,不僅需要訊號量機制,還需要額外的讀者計數和寫者計數。public static final object signal ne...