UDP 的每包循環負載平衡
我需要在多個“真實伺服器”之間對 UDP 流量進行負載平衡,並以真正的循環方式進行。我從 keepalived 開始,但意外地發現,LVS 將 UDP 流量視為“連接”(無論是 UDP ..)。實際上,這意味著來自特定客戶端的所有流量一直都流向同一個“真實伺服器”(這很重要,因為某些客戶端可能會產生如此多的流量,以至於單個後端將不堪重負) .
顯然,這是預期的行為,但是最近的 LVS 版本有一個“–ops”標誌,這使得 LVS 繞過其上述行為,以便獨立處理每個 UDP 數據報(這就是我想要的!)。但是(總是有一個但是..)這個功能沒有從 keepalived.conf 中暴露出來。
有什麼解決方案嗎,那會讓我
- 在 UDP 的後端之間進行循環分發
- 檢測“死”後端並將它們從循環中刪除(當它們“活著”時將它們添加回來也很有用)
顯然應該是基於Linux的。任何形式的 DNS 循環在這裡都不會真正起作用,因為客戶端不支持 DNS。
PS我將嘗試脈衝/食人魚,但通過閱讀我收集的文件,它也不會暴露“–ops”標誌。我還將嘗試mon(通過直接呼叫 ipvsadm 使mon檢查後端並添加/刪除 realservers)。
滿足要求如下:
我安裝了更新版本的 ipvsadm(及其核心模組),它支持
--ops
標誌 (1.26)。由於 keepalived 不會在其配置文件中公開此標誌,因此您必須手動應用它。幸運的是,您可以在創建“虛擬服務”之後執行此操作(就普通的 ipvsadm 而言,您可以先ipvsam -A
創建一個不帶 的虛擬服務--ops
,然後再ipvsadm -E
添加一個數據包調度)。由於keepalived 為您創建了虛擬服務,您所要做的就是在創建後對其進行編輯,這會在此虛擬伺服器獲得仲裁時發生(基本上,有足夠數量的工作真實伺服器)。這是它在
keepalived.conf
文件中的外觀:virtual_server <VIP> <VPORT> { lb_algo rr lb_kind NAT protocol UDP ... # Enable one-packet scheduling when quorum is gained quorum_up "ipvsadm -E -u <VIP>:<VPORT> --ops -s rr" ... realserver definitions, etc ... }
這行得通,但我在這個設置中遇到了一些問題(有點):
quorum_up
在法定人數上升和腳本執行之間存在很小的時間間隔(不到一秒,更像是 1/10) 。任何在這段時間內通過 director 的數據報都會在 ipvsadm 中創建一個連接條目,並且即使在--ops
添加了標誌之後,來自該源主機/埠的進一步數據報也會停留在同一個 realserver 上。通過確保虛擬服務在創建後永遠不會被刪除,您可以最大限度地減少發生這種情況的機會。你可以通過指定inhibit_on_failure
標記您的 realserver 定義,以便在相應的 realserver 關閉時不會刪除它們(當所有 realserver 被刪除時,虛擬服務也會被刪除),而是將它們的權重設置為零(然後它們停止接收流量)。因此,數據報唯一可以通過的時間是在 keepalived 啟動期間(假設您當時至少有一個 realserver 啟動,因此將立即獲得仲裁)。- 當
--ops
處於活動狀態時,director 不會重寫 realservers 發送給客戶端的數據報的源主機/埠,因此源主機/埠是已發送此特定數據報的 realserver 的主機/埠。這可能是一個問題(這是給我的客戶的)。您可以通過SNAT
使用 iptables 來修改這些數據報。- 當director 處於負載狀態時,我注意到顯著的系統CPU 負載。事實證明,CPU 被 ksoftirqd 佔用。如果你關閉它就不會發生
--ops
。據推測,問題在於數據包調度算法是在每個數據報上觸發的,而不僅僅是“連接”中的第一個數據報(如果這甚至適用於 UDP..)。我實際上還沒有找到“修復”它的方法,但也許我還沒有足夠努力。系統有一些特定的負載要求,在該負載下,處理器的使用不會達到最大值;也沒有任何失去的數據報,所以這個問題不被認為是一個阻礙。儘管如此,它仍然相當令人擔憂。總結:設置確實有效(也在負載下),但是必須跳過箍和我遇到的問題(特別是№3 ..也許有人知道解決方案?),這意味著,給定時間,我會’我使用了一個使用者空間程序(可能是用 C 編寫的)來偵聽 UDP 套接字並在 realservers 之間分發接收到的數據報,並
SNAT
在 iptables 中為我檢查 realservers 的健康狀況以重寫源主機/埠和為 HA 保持 VRRP 模式。