Google 是如何做負載均衡的?

2021-07-25 15:18:06 字數 2279 閱讀 5606

google 使用的技術一般都自帶光環,吸引程式設計師的注意,基礎設施方面的東西就更是如此,年初 google 發布了篇**介紹內部的負載均衡器的實現,讓我們有機會一睹可能是全球最好的負載均衡器。

通常情況下的負載均衡要在靈活性和效能之間做權衡,使用者態軟體層面有 haproxy 和 nginx 這樣的老牌負載均衡軟體,他們一般配置和使用起來都比較容易,但是由於需要資料報從網絡卡到核心再到軟體一層層向上處理,再一層層向下**,堆疊比較深單機效能通常都比較一般。為了提高單機效能,減少堆疊層級就有了 linux 裡華人之光的 lvs,工作在核心層的負載均衡器,效能有著數量級的提高,然而配置起來相對也比較複雜而且對網路條件要求也有特殊要求。那 google 有什麼秘密的配方來達到高效能呢?

一般來說負載均衡器本身就是後端服務橫向擴充套件的乙個接入點,對於一般站點乙個負載均衡器就夠了,然而應對 google 這種級別的流量,負載均衡器本身也要能橫向擴充套件,還要處理負載均衡器的高可用,google 又是如何做到的呢?

以我們訪問 www.google.com 為例,第一步 dns 伺服器會根據請求的位置返回乙個離請求地理位置最近的 vip 位址,先在 dns 這一層做乙個橫向擴充套件。接下來請求達到 vip 對應的路由器,路由器通過 ecmp 協議,可以將請求平均分配到下面對等的多個負載均衡器上,這樣在路由器這一層做了個負載均衡,讓後面的負載均衡器也實現了橫向擴充套件。再往下是乙個類似於 lvs 中 dr 模式的分發,負載均衡器將請求包**給伺服器同時將源位址改為客戶請求時的位址,伺服器響應時將響應包的源位址改為 vip 的位址直接打給路由器而不通過負載均衡器來降低負載均衡器壓力。流程圖如下

對了,google 的這個負載均衡器叫 maglev,磁懸浮列車的意思。自然是要做到極致的效能,只看流程似乎和 lvs 中 dr 模式很類似,但內部就完全不一樣了。

簡單的說雖然 lvs 已經做到 linux 核心裡了,但是在 google 看來 linux 是效能的瓶頸,到 lvs 之前還要經過完整的 tcp/ip 協議棧以及核心的一系列 filter 模組,而這些對於**來說是沒有必要的。於是 google 的做法就是簡單粗暴的繞過核心,把 maglev 直接架在網絡卡上對接網絡卡的輸入和輸出佇列,來乙個資料報也不需要完整的 tcp/ip 協議棧的解析,進來的包只要分析前幾個位元組,拿出源位址,源埠,目標位址,目標埠和協議號這個五元組對於**來說就已經足夠了。剩下的諸如 payload,序列號之類的東西統統不關心直接塞到網絡卡輸出口給後面就行了。

前幾天聽美團的介紹他們的負載均衡器是用的類似的思路用 dpdk 直接在網絡卡上編寫應用,效能相對 lvs 就有數倍的提公升。看 maglev 的實現為了榨乾效能是直接寫在網絡卡上的,都沒有 dpdk 之類的封裝。繞過核心就可以自己分配記憶體管理記憶體就可以進一步的壓榨效能。**中可以看到 maglev 是直接和網絡卡共享記憶體的,這樣就不需要將資料報再從網絡卡進行一次複製到負載均衡器中,也不需要把資料報再從負載均衡器複製到網絡卡,網絡卡入口佇列,負載均衡器,網絡卡出口佇列共享乙個資料池空間,三個指標不斷的移動處理資料報,可謂是在記憶體這裡做到了極致。

當然諸如 cpu 繫結,每個 cpu 專職處理乙個執行緒來避免 cache miss,memory contention 這種常規優化也是都有的。最終的效果就是處理乙個資料報平均需要 350ns,而效能發生抖動的情況一般是由於網絡卡發資料報是批量的或者要等待乙個 timer 的中斷,而這個中斷的時間是 50us 所以當流量小的時候這個延遲可能會達到 50us。(我覺得 google 這麼寫其實是在炫耀自己效能好,瓶頸在網絡卡重新整理速度上,而不在負載均衡器上)

通常的負載均衡器都是乙個單點,而 maglev 是乙個集群,集群就會碰到很多的問題。嚴格來說負載均衡器不能算是乙個無狀態的服務,因為 tcp 連線本身是有狀態的,一組會話內的請求包必須**到相同的後端伺服器,不然伺服器端的 tcp 會話就亂套了。對於單點的負載均衡器來說很好解決,記錄個**表裡面有每個資料報的五元組和它第一**到哪台機器,來乙個新的資料報查這個表就知道給誰了。而像 maglev 這樣的集群資料報是通過路由器 ecmp 隨機分發的,第乙個資料報是這個 maglev node 處理,下乙個就不知道去哪個 maglev node 了。而且集群就會涉及滾動式的更新和隨機的故障,這樣本機的**表也就很可能會丟失。

之前聽美團的介紹,他們的做法是在多台機器之間做記憶體的同步每次更新都要進行一次同步來保證所有機器**表的一致。而 google 一幫人不愧是搞研究出身的,直接就上了一致性雜湊這個大殺器。這樣的話可以直接通過五元組雜湊到後端的一台固定伺服器,這樣硬生生的把有狀態服務做成了無狀態,如此一來 maglev 層面個就可以隨意的更新,上線下線了。順便的乙個好處就是後端增加下線伺服器都只會影響到當前這台機器所處理的連線不會造成所有連線的 rehash。當然只用乙個普通的一致性雜湊演算法也沒啥意思,google 為了自己的需求專門寫了個 maglev hashing

ClickHouse的負載均衡如何做。

1,負載均衡。目前我們公司後台使用clickhouse,來做資料的離線分析 配置為四台集群 shard 通過springboot clickhouse jdbc完成服務與clickhouse jdbc的連線 使用的是clickhouse官方,balancedclickhousedatasource ...

google是如何做測試?(三 四)

在谷歌,質量不等於測試,是的,我確定在其他所有的公司也都是這樣。質量不是被測出來的 這句陳詞濫調是再正確不過的了。不管汽車製造還是 軟體開發,如果在最初的設計建造的時候就有問題,那它永遠都會有問題。試問任何一家曾經被迫大量召回汽車的公司,逃避質量問題的代價是多麼的昂貴。但是,質量不是被測出來的 這句...

如何使用Apache做負載均衡

第一次看到這個標題時我也很驚訝,apache居然還能做負載均衡?真是太強大了。經過一番調查後發現的確可以,而且功能一點都不差。這都歸功於 mod proxy 這個模組。不愧是強大的apache啊。廢話少說,下面就來解釋一下負載均衡的設定方法。一般來說,負載均衡就是將客戶端的請求分流給後端的各個真實伺...