12.15 MGW——美團點評高性能四層負載均衡

本文整理自美團點評技術沙龍第14期:美團背後的故事-你不知道的美團雲。

美團點評技術沙龍由美團點評技術團隊主辦,每月一期。每期沙龍邀請美團點評及其他互聯網公司的技術專家分享來自一線的實踐經驗,覆蓋各主要技術領域。

目前沙龍會分別在北京、上海和廈門等地舉行,要參加下一次最新沙龍活動?趕快關注微信公眾號“美團點評技術團隊”。

本期沙龍包括三場講座:美團雲Docker平臺、美團雲對象存儲系統、美團四層負載均衡網關MGW。其他幾場講座的圖文實錄會陸續發表,請繼續關注。

前言

在高速發展的移動互聯網時代,負載均衡有著舉足輕重的地位,它是應用流量的入口,對應用的可靠性和性能起著決定性的作用,因此負載均衡需要滿足高性能、高可靠兩個特點。MGW是美團點評自研的一款四層負載均衡,主要用於替代原有環境的四層負載均衡LVS,目前處理著美團點評數十 Gbps的流量、上千萬的併發連接。本文主要介紹MGW是如何實現高性能、高可靠的。

什麼是負載均衡?

互聯網早期,業務流量比較小並且業務邏輯比較簡單,單臺服務器便可以滿足基本的需求;但隨著互聯網的發展,業務流量越來越大並且業務邏輯也越來越複雜,單臺機器的性能問題以及單點問題凸顯了出來,因此需要多臺機器來進行性能的水平擴展以及避免單點故障。但是要如何將不同的用戶的流量分發到不同的服務器上面呢?

MGW——美團點評高性能四層負載均衡

image.png

早期的方法是使用DNS做負載,通過給客戶端解析不同的IP地址,讓客戶端的流量直接到達各個服務器。但是這種方法有一個很大的缺點就是延時性問題,在做出調度策略改變以後,由於DNS各級節點的緩存並不會及時的在客戶端生效,而且DNS負載的調度策略比較簡單,無法滿足業務需求,因此就出現了負載均衡。

MGW——美團點評高性能四層負載均衡

image.png

客戶端的流量首先會到達負載均衡服務器,由負載均衡服務器通過一定的調度算法將流量分發到不同的應用服務器上面,同時負載均衡服務器也會對應用服務器做週期性的健康檢查,當發現故障節點時便動態的將節點從應用服務器集群中剔除,以此來保證應用的高可用。

MGW——美團點評高性能四層負載均衡

image.png

負載均衡又分為四層負載均衡和七層負載均衡。四層負載均衡工作在OSI模型的傳輸層,主要工作是轉發,它在接收到客戶端的流量以後通過修改數據包的地址信息將流量轉發到應用服務器。

七層負載均衡工作在OSI模型的應用層,因為它需要解析應用層流量,所以七層負載均衡在接到客戶端的流量以後,還需要一個完整的TCP/IP協議棧。七層負載均衡會與客戶端建立一條完整的連接並將應用層的請求流量解析出來,再按照調度算法選擇一個應用服務器,並與應用服務器建立另外一條連接將請求發送過去,因此七層負載均衡的主要工作就是代理。

既然四層負載均衡做的主要工作是轉發,那就存在一個轉發模式的問題,目前主要有四層轉發模式:DR模式、NAT模式、TUNNEL模式、FULLNAT模式。

MGW——美團點評高性能四層負載均衡

image.png

DR模式也叫作三角傳輸,通過修改數據包的目的MAC地址來讓流量經過二層轉發到達應用服務器,這樣應用服務器就可以直接將應答發給應用服務器,性能比較好。由於這種模式需要依賴二層轉發,因此它要求負載均衡服務器和應用服務器必須在一個二層可達的環境內,並且需要在應用服務器上配置VIP。

NAT模式通過修改數據包的目的IP地址,讓流量到達應用服務器,這樣做的好處是數據包的目的IP就是應用服務器的IP,因此不需要再在應用服務器上配置VIP了。缺點是由於這種模式修改了目的IP地址,這樣如果應用服務器直接將應答包發給客戶端的話,其源IP是應用服務器的IP,客戶端就不會正常接收這個應答,因此我們需要讓流量繼續回到負載均衡,負載均衡將應答包的源IP改回VIP再發到客戶端,這樣才可以保證正常通信,所以NAT模式要求負載均衡需要以網關的形式存在於網絡中。

TUNNEL模式的優缺點和DR是一樣的,並且TUNNEL模式要求應用服務器必須支持TUNNEL功能。

FULLNAT模式是在NAT模式的基礎上做一次源地址轉換(即SNAT),做SNAT的好處是可以讓應答流量經過正常的三層路由回到負載均衡上,這樣負載均衡就不需要以網關的形式存在於網絡中了,對網絡環境要求比較低,缺點是由於做了SNAT,應用服務器會丟失客戶端的真實IP地址。

image.png

下面詳細介紹一下FULLNAT模式。首先負載均衡上需要存在一個localip池,在做SNAT時的源IP就是從localip池中選擇的。當客戶端流量到達負載均衡設備以後,負載均衡會根據調度策略在應用服務器池中選擇一個應用服務器,然後將數據包的目的IP改為應用服務器的IP。同時從localip池中選擇一個localip將數據包的源IP改為localip,這樣應用服務器在應答時,目的IP是localip,而localip是真實存在於負載均衡上的IP地址,因此可以經過正常的三層路由到達負載均衡。由於FULLNAT比NAT模式多做了一次SNAT,並且SNAT中有選端口的操作,因此其性能要遜色於NAT模式,但是由於其較強的網絡環境適應性,我們選擇了FULLNAT作為MGW的轉發模式。

為什麼選擇自研四層負載均衡?

選擇自研四層負載均衡的原因主要有兩個:第一個是考慮到硬件負載均衡成本比較高;第二個,隨著美團點評業務流量越來越大,LVS出現了性能瓶頸以及運維成本的上升問題。

硬件負載均衡成本問題

  1. 硬件成本:中低端硬件負載均衡價格在數十萬,高端的上百萬,價格非常昂貴。當我們需要組成一個高可用集群時,需要數臺機器,成本異常高。

  2. 人力成本:硬件負載均衡功能比較強大,配置比較靈活,這也導致在維護上,我們需要一些經過專業培訓的人員,就增加了人力成本。

  3. 時間成本:當使用的過程中遇到bug或者新需求需要廠商提供新版本的時候,我們需要經過繁瑣的流程向廠商上報,然後廠商再發布新版本供我們升級,時間週期非常長,在高速發展的互聯網行業,這種週期是無法接受的。

LVS的性能問題

最初美團點評使用的是LVS+Nginx組成的負載均衡結構,LVS做四層負載均衡,Nginx做七層負載均衡,但是隨著美團點評流量的高速增長(幾個月內無論新建連接數還是吞吐量都有三倍的增長),LVS故障頻發,性能上出現瓶頸,因此我們自研了一款高性能、高可靠的四層負載均衡MGW來替換LVS。

MGW如何實現高性能

下面通過對比LVS的一些性能瓶頸來介紹MGW是如何實現高性能的。

中斷問題以及協議棧路徑性能過長問題

中斷是影響LVS性能最重要的一個因素,假如我們一秒需要處理600萬的數據包,每6個數據包產生一個硬件中斷的話,那一秒就會產生100萬個硬件中斷,每一次產生硬件中斷都會打斷正在進行密集計算的負載均衡程序,中間產生大量的cache miss,對性能的影響異常大。

同時由於LVS是基於內核netfilter開發的一個應用程序,而netfilter是運行在內核協議棧的一個鉤子框架。這就意味著當數據包到達LVS時,已經經過了一段很長的協議棧處理,但是這段處理對於LVS來說都不是必需的,這也造成了一部分不必要的性能損耗。

MGW——美團點評高性能四層負載均衡

image.png

針對這兩個問題,解決方法是使用輪詢模式的驅動以及做kernel bypass,而DPDK提供的用戶態PMD驅動恰好可以解決這兩個問題。DPDK在設計時使用了大量硬件相關特性比如numa、 memory channel、 DDIO等,對性能優化非常大,同時提供了比較多網絡方面的庫,可以大大減小開發難度,提高開發效率。因此選擇DPDK作為MGW的開發框架。

由於內核是一個比較通用的應用程序,因此它並沒有對一些特定場景做一些定製設計,這就導致一些公共的數據結構需要鎖的保護。下面介紹一下出現鎖的原因和MGW的解決方法。

MGW——美團點評高性能四層負載均衡

image.png

首先介紹一下RSS(Receive Side Scaling),RSS是一個通過數據包的元組信息將數據包散列到不同網卡隊列的功能,這時候不同的CPU再去對應的網卡隊列讀取數據進行處理,就可以充分利用CPU資源。之前介紹MGW使用FULLNAT的模式,FULLNAT會將數據包的元組信息全部改變,這樣同一個連接,請求和應答方向的數據包有可能會被RSS散列到不同的網卡隊列中,在不同的網卡隊列也就意味著在被不同的CPU進行處理,這時候在訪問session結構的時候就需要對這個結構進行加鎖保護。

解決這個問題的方法有兩種,一種就是在做SNAT選端口的時候,通過選擇一個端口lport0讓RSS(cip0, cport0, vip0, vport0) = RSS(dip0, dport0, lip0, lport0)相等;另外一種方法就是我們為每個CPU分配一個localip,在做SNAT選IP的時候,不同的CPU選擇自己的localip,等應答回來以後,再通過lip和CPU的映射關係,將指定目的IP的數據包送到指定隊列上。

由於第二種方法恰好可以被網卡的flow director特性支持,因此我們選擇了第二種方法來去掉session結構的鎖。

MGW——美團點評高性能四層負載均衡

image.png

flow director可以根據一定策略將指定的數據包送到指定網卡隊列,其在網卡中的優先級要比RSS高,因此我們在做初始化的時候就為每個CPU分配一個localip,比如為cpu0分配lip0,為cpu1分配lip1,為cpu2分配lip2,為cpu3分配lip3。 當一個請求包(cip0, cport0, vip0, vport0)到達負載均衡後,被RSS散列到了隊列0上,這時這個包被cpu0處理。cpu0在對其做fullnat時,選擇cpu0自己的localip lip0,然後將數據包(lip0, lport0, dip0, dport0)發到應用服務器,在應用服務器應答後,應答數據包(dip0, dport0, lip0,

lport0)被髮到了負載均衡服務器。此時我們就可以在flow director下一條將目的IP為lip0的數據包送到隊列0的規則,這樣應答數據包就會被送到隊列0讓cpu0處理。這時候CPU在對同一個連接兩個方向的數據包進行處理的時候就是完全串行的一個操作,也就不要再對session結構進行加鎖保護了。

上下文切換

image.png

在設計時,希望控制平面與數據平面完全分離,數據平面專心做自己的處理,不被任事件打斷。因此將CPU分成兩組,一組用作數據平面一組用做控制平面。同時,對數據平面的CPU進行CPU隔離,這樣控制平面的進程就不會調度到數據平面的這組CPU上面了;對數據平面的線程進行CPU綁定,這樣就可以讓每個數據線程獨佔一個CPU。 其他的控制平面的程序比如Linux kernel、 SSH等都跑在控制平面的這組CPU上。

MGW如何做到高可靠

下面從MGW集群、MGW單機以及應用服務器層這三個層介紹MGW如何在每一層實現高可靠。

集群的高可靠

MGW——美團點評高性能四層負載均衡

image.png

MGW使用OSPF+ECMP的模式組成集群,通過ECMP將數據包散列到集群中各個節點上,再通過OSPF保證單臺機器故障以後將這臺機器的路由動態的剔除出去,這樣ecmp就不會再給這臺機器分發流量,也就做到了動態的failover。

MGW——美團點評高性能四層負載均衡

image.png

傳統的ecmp算法有一個很嚴重的問題,當集群中節點數量發生變化以後,會導致大部分流量的路徑發生改變,發生改變的流量到達其他MGW節點上時是找不到自己的session結構的,這就會導致大量的連接出現異常,對業務影響很大,並且當我們在對集群做升級操作時會將每個節點都進行一次下線操作,這樣就加重了這個問題的影響。

一種解決方式是使用支持一致性hash的交換機,這樣在節點發生變化的時候,只有發生變化的節點上面的連接會有影響,其他連接都會保持正常,但是支持這種算法的交換機比較少,並且也沒有完全實現高可用,因此我們做了集群間的session同步功能。

MGW——美團點評高性能四層負載均衡

image.png

集群中每個節點都會全量的將自己的session同步出去,使集群中每個節點都維護一份全局的session表,因此無論節點變化以後流量的路徑以任何形式改變,這些流量都可以找到自己的session結構,也就是說可以被正常的轉發,這樣就可以在集群中節點數量發生變化時保證所有連接正常。

在設計的過程中主要考慮了兩個問題:第一個是故障切換,第二個是故障恢復以及擴容。

故障切換

MGW——美團點評高性能四層負載均衡

image.png

在故障切換的問題上,我們希望在機器故障以後,交換機可以立刻將流量切到其他機器上,因為流量不切走,意味著到達這臺機器流量會被全部丟掉,產生大量丟包。經過調研測試發現,當交換機側全部使用物理接口並且服務器側對接口進行斷電時,交換機會瞬間將流量切換到其他機器上。通過一個100ms發兩個包的測試(客戶端和服務端各發一個),這種操作方法是0丟包的。

由於故障切換主要依賴於交換機的感知,當服務器上出現一些異常,交換機感知不到時,交換機就無法進行故障切換操作,因此需要一個健康自檢程序,每半秒進行一次健康自檢,當發現服務器存在異常時就對服務器執行網口斷電操作,從而讓流量立刻切走。

故障切換主要依賴於網口斷電操作並且網卡驅動是跑在主程序裡面的,當主程序掛掉以後,就無法再對網口執行斷電操作了,因此為了解決這個問題,主進程會捕獲異常信號,當發現異常時就對網卡進行斷電操作,在斷電操作結束以後再繼續將信號發給系統進行處理。

經過以上設計,MGW可以做到升級操作0丟包,主程序故障0丟包,其他異常(網線等)會有一個最長500ms的丟包,因為這種異常需要靠自檢程序去檢測,而自檢程序的週期是500ms。

故障恢復與擴容

MGW——美團點評高性能四層負載均衡

image.png

無論是在進行故障恢復還是擴容操作,都會導致集群節點數量發生變化,這樣也就會導致流量路徑發生變化。當變化的流量到達集群中原有的節點時,因為原有節點都維護著一個全局的session表,因此這些流量是可以被正常轉發的;但是如果流量到達了新機器上,這個機器是沒有全局session表的,那麼這部分流量就會全部被丟棄。為了解決這個問題,MGW在上線以後會經歷一個預上線的中間狀態,在這個狀態上,MGW不會讓交換機感知到自己上線了,這樣交換機也就不會把流量切過來。首先MGW會對集群中其他節點發送一個批量同步的請求,其他節點收到請求以後會將自己的session全量的同步到新上線的節點上,新上線節點在收到全部session以後才會讓交換機感知到自己上線,這時交換機再將流量切過來就可以正常被轉發出去了。

在這個過程中主要存在兩點問題。

第一個問題是,由於集群中並沒有一個主控節點來維護一個全局的狀態,如果request報丟失或者session同步的數據丟失的話,那新上線節點就沒辦法維護一個全局的session狀態。但是考慮到所有節點都維護著一個全局的session表,因此所有節點擁有的session數量都是相同的,那麼就可以在所有節點每次做完批量同步以後發送一個finish消息,finish消息中帶著自己擁有的session數量。當新上線節點收到finish消息以後,便會以自己的session數量與finish中的數量做對比。當達到數量要求以後,新上線節點就控制自己進行上線操作。否則在等待一定的超時時間以後,重新進行一次批量同步操作,直到達到要求為止。

另外一個問題是在進行批量同步操作時,如果出現了新建連接,那麼新建連接就不會通過批量同步同步到新上線的機器上。如果新建連接特別多,就會導致新上線機器一直達不到要求。因此,需要保證處於預上線狀態的機器能接收到增量同步數據,因為新建連接可以通過增量同步同步出來。通過增量同步和批量同步就可以保證新上線機器可以最終獲得一個全局的session表。

單機高可靠

MGW——美團點評高性能四層負載均衡

image.png

在單機高可靠方面,MGW做了一個自動化測試平臺,自動化平臺通過連通性和配置的正確性來判斷一個測試用例是否執行成功,失敗的測試用例平臺可以通過郵件通知測試人員。在每次新功能迭代結束以後,都會將新功能的測試用例加到自動化平臺裡面,這樣在每次上線之前都進行一次自動化測試,可以大大避免改動引發的問題。

在之前,每次上線之前都需要進行一次手動的迴歸測試,迴歸測試非常耗時並且很容易遺漏用例,但是為了避免改動引發新問題又不得不做,有了自動化測試平臺以後,大大提高了迴歸測試的效率和可靠性。

RS可靠性

節點平滑下線

MGW——美團點評高性能四層負載均衡

image.png

在RS可靠性方面,MGW提供了節點平滑下線功能,主要是為了解決當用戶需要對RS進行升級操作時,如果直接將需要升級的RS下線,那這個RS上存在的所有連接都會失敗,影響到業務。此時如果調用MGW的平滑下線功能,MGW就可以保證此RS已有連接正常工作,但不會往上面調度新的連接。當所有已有連接結束以後,MGW會上報一個結束的狀態,用戶就可以根據這個結束的狀態對RS進行升級操作,升級後再調用上線接口讓這個RS器進行正常的服務。如果用戶平臺支持自動化應用部署,那就可以通過接入雲平臺使用平滑下線功能,實現完全自動化且對業務無影響的升級操作。

一致性源IP Hash調度器

源IP Hash調度器主要是保證相同的客戶端的連接被調度到相同應用服務器上,也就是說建立一個客戶端與應用服務器一對一的映射關係。普通的源IP Hash調度器在應用服務器發生變化以後會導致映射關係發生改變,會對業務造成影響。

因此我們開發了一致性源IP Hash調度器,保證在應用服務器集群發生變化時,只有發生變化的應用服務器與客戶端的映射關係發生改變,其他都是不變的。

MGW——美團點評高性能四層負載均衡

image.png

為了保證流量的均衡,首先在hash環上分配固定數量的虛擬節點,然後將虛擬機節點均衡的重分佈到物理節點上,重分佈算法需要保證兩點:

  1. 在物理節點發生變化時,只有少數虛擬節點映射關係發生變化,也就是要保證一致性Hash的基本原則。

  2. 因為MGW是以集群的形式存在的,當多個應用服務器發生上線下線操作時,反饋到不同的MGW節點上就有可能會出現順序不一致的問題,因此無論不同的MGW節點產生何種應用服務器上下線順序,都需要保證最終的映射關係一致,因為如果不一致就導致相同客戶端的連接會被不同的MGW節點調度到不同的應用服務器上,也就違背了源IP Hash調度器的原則。

綜合以上兩點,Google Maglev負載均衡的一致性Hash算法是一個很好的例子,在paper中有詳細的介紹,這裡就不過多討論了。

總結

經過美團點評以及美團雲的流量驗證,MGW無論在傳統網絡環境還是overlay的大二層環境下都有出色的性能和穩定性表現。在業務場景方面涵蓋數據庫業務,千萬級別的長連接業務,嵌入式業務,存儲業務以及酒店、外賣、團購等Web應用業務。在業務需求快速變化的環境下,MGW在不斷完善自身功能,在各種業務場景下都有良好的表現。 在未來的一段時間內,MGW除了會完善四層的功能需求外,也會考慮向七層方向發展。

  1. DPDK.

  2. LVS.

  3. Eisenbud D E, Yi C, Contavalli C, et al. Maglev: A Fast and Reliable Software Network Load Balancer.


個人介紹:

高廣超:多年一線互聯網研發與架構設計經驗,擅長設計與落地高可用、高性能、可擴展的互聯網架構。

本文首發在 高廣超的簡書博客 轉載請註明!


分享到:


相關文章: