一、什麼是負載均衡
負載均衡的發展曆程
1996 f5成立
1998 lvs項目成立
2000 haproxy項目成立
2004 nginx推出公共版本
2004 f5推出tmos平台
2007 f5開始提供應用傳遞(adc)産品
負載平衡、ssl解除安裝、壓縮優化、tcp連接配接優化
一台伺服器的處理能力,主要受限于伺服器自身的可擴充硬體能力。是以,在需要處理大量使用者請求的時候,通常都會引入負載均衡器,将多台普通伺服器組成一個系統,來完成高并發的請求處理任務。
1996年之後,出現了新的網絡負載均衡技術。通過設定虛拟服務位址(ip),将位于同一地域(region)的多台伺服器虛拟成一個高性能、高可用的應用服務池;再根據應用指定的方式,将來自用戶端的網絡請求分發到伺服器池中。網絡負載均衡會檢查伺服器池中後端伺服器的健康狀态,自動隔離異常狀态的後端伺服器,進而解決了單台後端伺服器的單點問題,同時提高了應用的整體服務能力。
二、負載均衡的演進

網絡負載均衡主要有硬體與軟體兩種實作方式,主流負載均衡解決方案中,硬體廠商以f5為代表,軟體主要為nginx與lvs。但是,無論硬體或軟體實作,都逃不出基于四層互動技術的“封包轉發”或基于七層協定的“請求代理”這兩種方式。 四層的轉發模式通常性能會更好,但七層的代理模式可以根據更多的資訊做到更智能地分發流量。一般大規模應用中,這兩種方式會同時存在。
2007年f5提出了adc(application delivery controller)的概念為傳統的負載均衡器增加了大量的功能,常用的有:ssl解除安裝、壓縮優化和tcp連接配接優化。nginx也支援很多adc的特性,但f5的中高端型号會通過硬體加速卡來實作ssl解除安裝、壓縮優化這一類cpu密集型的操作,進而可以提供更好的性能。
三、硬體負載均衡的痛點
f5的硬體負載均衡産品又分單機big ip系列和叢集visrion系列,都是x86架構,配合自研的tmos(traffic management operating system),再加上硬體加速卡(cavium提供)處理ssl和壓縮等cpu密集型操作。以單機中的中端版本big ip 4200v為例,從datasheet了解到能支撐每秒30萬建立連接配接數,1000萬并發連接配接數,10g資料吞吐量。而這樣的性能實際上lvs是可能在通用伺服器上達到的。viprion系列本質上通過背闆交換将多塊刀片伺服器內建在一起,通過橫向擴充來提升性能。
硬體負載均衡在功能、易用性和可擴充性上都做得不錯,但是也有不少缺點。從商業角度來說,硬體負載均衡産品過于昂貴,高端産品動辄五十萬甚至數百萬的價格對于使用者是幾乎不可承受的負擔。從使用角度來說,硬體負載均衡是黑盒,有bug需要聯系廠商等待解決,時間不可控、新特性疊代緩慢且需資深人員維護更新,也是變相增加昂貴的人力成本。
(一)lvs的痛點
lvs最常用的有nat、dr以及新的full nat模式。上圖比較了幾種常見轉發模式的優缺點。
我們認為lvs的每種模式都有其優點和缺點,但最大的問題是其複雜性。相信很多朋友看到這三種方式的優缺點、還有f5的單臂模式、雙臂模式都會有雲裡霧裡的感覺。
(二)lvs叢集的痛點
雪上加霜的是咱們還需要考慮lvs的性能擴充和容災方法,這使得整個方案更加的複雜。常見的有基于keepalived的主備方式和ecmp兩種。
keepalived主備模式裝置使用率低;不能橫向擴充;vrrp協定,有腦裂的風險。而ecmp的方式需要了解動态路由協定,lvs和交換機均需要較複雜配置;交換機的hash算法一般比較簡單,增加删除節點會造成hash重分布,可能導緻目前tcp連接配接全部中斷;部分交換機的ecmp在處理分片包時會有bug。
四、vortex負載均衡器的設計理念
可靠性: ecmp+一緻性哈希保證連接配接不中斷 當負載均衡器發生變化 當後端伺服器發生變化 當兩者同時發生變更 可伸縮性 橫向擴充:ecmp叢集 縱向擴充:dpdk提升單機性能 虛拟化網絡中的dr轉發模式
使用者使用負載均衡器最重要的需求是“high availability”和“scalability”,vortex的架構設計重心就是滿足使用者需求,提供極緻的“可靠性”和“可收縮性”,而在這兩者之間我們又把“可靠性”放在更重要的位置。
值得一提的是今年3月舉辦的第十三屆網絡系統設計與實作usenix研讨會(nsdi '16)上, 來自谷歌、加州大學洛杉矶分校、spacex公司的工程師們分享了《maglev:快速、可靠的軟體網絡負載均衡器》,介紹了從2008年開始在生産環境投入使用的軟體負載均衡器。其設計理念和我們非常相似,同樣是ecmp + 一緻性哈希;同樣是kernel bypass模式;單機性能也和我們的vortex非常接近。
(一)vortex的high availability實作
四層負載均衡器的主要功能是将收到的資料包轉發給不同的後端伺服器,但必須保證将五元組相同的資料包發送到同一台後端伺服器,否則後端伺服器将無法正确處理該資料包。
以常見的http連接配接為例,如果封包沒有被發送到同一台後端伺服器,作業系統的tcp協定棧無法找到對應的tcp連接配接或者是驗證tcp序列号錯誤将會無聲無息的丢棄封包,發送端不會得到任何的通知。如果應用層沒有逾時機制的話,服務将會長期不可用。vortex的可靠性設計面臨的最大問題就是如何在任何情況下避免該情況發生。vortex通過ecmp叢集和一緻性哈希來實作極緻程度的可靠性。
(二)可靠性: ecmp+一緻性哈希保證連接配接不中斷
1、可靠性:當負載均衡器發生變化
首先,我們來考察一下負載均衡伺服器變化場景。 這種場景下,可能由于負載均衡伺服器故障被動觸發,也可能由于運維需要主動增加或者減少負載均衡伺服器。此時交換機會通過動态路由協定檢測負載均衡伺服器叢集的變化,但除思科的某些型号外大多數交換機都采用簡單的取模算法,導緻大多數資料包被發送到不同的負載均衡伺服器。
vortex伺服器的一緻性雜湊演算法能夠保證即使是不同的vortex伺服器收到了資料包,仍然能夠将該資料包轉發到同一台後端伺服器,進而保證客戶應用對此類變化無感覺,業務不受任何影響。
這種場景下,如果負載均衡器是lvs且采用rr (round robin)算法的話,該資料包會被送到錯誤的後端伺服器,且上層應用無法得到任何通知。如果lvs配置了sh(source hash)算法的話,該資料包會被送到正确的後端伺服器,上層應用對此類變化無感覺,業務不受任何影響;如果負載均衡器是nginx的話,該資料包會被tcp協定棧無聲無息地丢棄,上層應用不會得到任何通知。
2、可靠性:後端伺服器發生變化
其次,來考察後端伺服器變化的場景。 這種場景下,可能由于後端伺服器故障由健康檢查機制檢查出來,也可能由于運維需要主動增加或者減少後端伺服器。此時,vortex伺服器會通過連接配接追蹤機制保證目前活動連接配接的資料包被送往之前選擇的伺服器,而所有建立連接配接則會在變化後的伺服器叢集中進行負載分擔。
同時,vortex一緻性雜湊演算法能保證大部分建立連接配接與後端伺服器的映射關系保持不變,隻有最少數量的映射關系發生變化,進而最大限度地減小了對用戶端到端的應用層面的影響。這種場景下,如果負載均衡器是lvs且sh算法的話,大部分建立連接配接與後端伺服器的映射關系會發生變化。某些應用,例如緩存伺服器,如果發生映射關系的突變,将造成大量的cache miss,進而需要從資料源重新讀取内容,由此導緻性能的大幅下降。而nginx在該場景下如果配置了一緻性哈希的話可以達到和vortex一樣的效果。
3、可靠性:同時發生變化
最後,讓我們來看一下負載均衡伺服器和後端伺服器叢集同時變化的場景。 在這種場景下,vortex能夠保證大多數活動連接配接不受影響,少數活動連接配接被送往錯誤的後端伺服器且上層應用不會得到任何通知。并且大多數建立連接配接與後端伺服器的映射關系保持不變,隻有最少數量的映射關系發生變化。
如果負載均衡器是lvs且sh算法的話幾乎所有活動連接配接都會被送往錯誤的後端伺服器且上層應用不會得到任何通知。大多數建立連接配接與後端伺服器的映射關系同樣也會發生變化。如果是nginx的話因為交換機将資料包送往不同的nginx伺服器,幾乎所有資料包會被無聲無息地丢棄,上層應用不會得到任何通知。
4、可靠性:總結
(三)可收縮性:基于ecmp叢集的scaling out設計
vortex采用動态路由的方式通過路由器ecmp(equal-cost multi-path routing)來實作vortex叢集的負載均衡。一般路由機支援至少16或32路ecmp叢集,特殊的sdn交換機支援多達256路ecmp叢集。而一緻性哈希的使用是的ecmp叢集的變化對上層應用基本無感覺,使用者業務不受影響。
1、可收縮性: 基于dpdk的scaling up設計
雖然ecmp提供了良好的scaling out的能力,但是考慮到網絡裝置的價格仍然希望單機性能夠盡可能的強。例如,轉發能力最好是能夠達到10g甚至40g的線速,同時能夠支援盡可能高的每秒建立連接配接數。vortex利用dpdk提供的高性能使用者空間 (user space) 網卡驅動、高效無鎖資料結構成功的将單機性能提升到轉發14m pps(10g, 64位元組線速),建立連接配接200k cps以上。
核心不是解決方案,而是問題所在!
從上圖可以看到随着高速網絡的發展64位元組小包線速的要求越來越高,對10g網絡來說平均67ns,對40g網絡來說隻有17ns。而于此同時cpu、記憶體的速度提升卻沒有那麼多。以2g主頻的cpu為例,每次命中l3緩存的讀取操作需要約40個cpu周期,而一旦沒有命中緩存從主存讀取則需要140個cpu周期。
為了達到線速就必須采用多核并發處理、批量資料包處理的方式來攤銷單個資料包處理所需要的cpu周期數。此外,即使采用上述方式,如果沒有得到充分的優化,發生多次cache miss或者是memory copy都無法達到10g線速的目标。
2、可收縮性: 基于dpdk的scaling up設計
像nginx這樣的代理模式,轉發程式因為需要tcp協定棧的處理以及至少一次記憶體複制性能要遠低于lvs。而lvs又因為通用kernel的限制,會考慮節省記憶體等設計政策,而不會向vortex一樣在一開始就特别注重轉發性能。例如lvs預設的連接配接追蹤hash表大小為4k,而vortex直接使用了50%以上的記憶體作為連接配接追蹤表。
vortex通過dpdk提供函數庫充分利用cpu和網卡的能力進而達到了單機10g線速的轉發性能。
使用者空間驅動,完全zero-copy 采用批處理攤銷單個封包處理的成本 充分利用硬體特性 intel datadirect i/o technology (intel ddio) numa huge pages,cache alignment,memory channel use
vortex直接采用多隊列10g網卡,通過rss直接将網卡隊列和cpu core綁定,消除線程的上下文切換帶來的開銷。vortex線程間采用高并發無鎖的消息隊列通信。除此之外,完全不共享狀态進而保證轉發線程之間不會互相影響。vortex在設計時盡可能的減少指針的使用、采用連續記憶體資料結構來降低cache miss。通過這樣一系列精心設計的優化措施,vortex的單機性能遠超lvs。
3、可收縮性: 虛拟化網絡中的dr轉發模式
基于dr轉發方式
lvs支援四種轉發模式:nat、dr、tunnel和fullnat,其實各有利弊。vortex在設計之初就對四種模式做了評估,最後發現在虛拟化的環境下dr方式在各方面比較平衡,并且符合我們追求極緻性能的理念。
dr方式最大的優點是絕佳的性能,隻有request需要負載均衡器處理,response可以直接從後端伺服器傳回客戶機,不論是吞吐還是延時都是最好的分發方式。
其次,dr方式不像nat模式需要複雜的路由設定,而且不像nat模式當client和後端伺服器處于同一個子網就無法正常工作。dr的這個特性使他特别合适作為内網負載均衡。
此外,不像fullnat一樣需要先修改源ip再使用 toa 傳遞源位址,還得在負載均衡器和後端伺服器上都編譯非主線的kernel module,dr可以kiss(keep it simple, stupid)地将源位址傳遞給後端伺服器。
最後,虛拟化環境中已經采用overlay虛拟網絡了,是以tunnel的方式變得完全多餘。而dr方式最大的缺點:需要lb和後端伺服器在同一個二層網絡,而這在ucloud的虛拟化網絡中完全不是問題。主流的sdn方案追求的正是大二層帶來的無縫遷移體驗,且早已采用各種優化手段(例如arp代理)來優化大二層虛拟網絡。
q&a
q1:請問您對haproxy有啥看法?
a1:haproxy其實和nginx基本功能、性能都差不多。但是haproxy的社群沒有nginx活躍,而且研發長期就隻有1、2個人吧。haproxy還沒有支援http 2.0,這也和他研發人員比較少有關。
q2:f5負載均衡的時候主要監控注意那幾點?
a2:f5負載均衡器,最重要就是并發連接配接數和cpu的監控了。另外f5的irule很強大,但一定要記住,代價是cpu。
q3:還有就是遇到過負載均衡的時候有的伺服器沒有壓力,怎麼去快快速排查原因?
a3:這個一般就是檢視負載均衡器上的健康檢查,看伺服器的狀态了;還有就是要看是不是開啟了連接配接保持模式。
q4:“四層的問題交給四層去解決”怎麼了解?
a4:這個以lvs和nginx為例,lvs的性能肯定超過nginx很多,但是特性沒nginx豐富呀。如果是小網站問題不大,單跑nginx可以,如果流量大了,一般還是會前置四層的負載均衡吧。
q5:前面提到的10g負載均衡,其實差别很大的,是指哪塊?
a5:主要還是和測試方法有關。如果是長連接配接,每個封包都1500的話,lvs也可以達到10g帶寬,可是這時候pps可能還不到1m,而cps隻有1.
q6:如果正在轉發封包的均衡器發生單點故障,有沒有什麼機制保證順利轉發?
a6:如果是nginx的話,無解,因為tcp協定棧就會丢棄不正确的連接配接;如果是lvs的話,全文也說過用sh算法的可以保持客戶連接配接不中斷;也可以用我們ulb。
q7:vortex有開源的計劃嗎?
a7:在開發之初就有考慮開源的,後續有進展會第一時間告知大家!
q8:vortex高可用是采用何種方案?
a8:ecmp + 一緻性哈希。
q9:4層和7層應用的主要優缺點是什麼?
a9:4層性能好;7層功能豐富;大多數應用場合還是會同時存在。
q10:想問下對于tcp的優化是指系統層面的參數優化,還是有别的優化情況?
a10:vortex現在是bypass kernel的,他其實完全省去了tcp協定棧。
q11:可以對不同種類的業務進行分流嗎?
a11:四層負載均衡一般是隻對不同的目的ip+port來識别service的;如果你的問題不是這個場景的話,就需要七層負載均衡了。
q12:後端節點探測提供哪幾種方式?
a12:目前tcp是通過syn去探測的,udp是通過ping去探測的。後期我們也打算開放api,讓使用者自己去設定。
q13:如果進行機房災備建設,該怎麼樣進行負載?有好的建議嗎?
a13:好問題。ucloud即将推出“可用區”的功能,未來我們的負載均衡申請後可以直接在不同可用區部署,進而提供跨機房災備的能力。
q14:營運商在負載均衡設計時一般如何考慮?與其他行業有何不同?
a14:營運商有錢,會配置比較高端的f5裝置。另外營運商有時會用到一些content switching的功能。
q15:這負載均衡具有分發到背景服務日志記錄和是否請求成功記錄?
a15:這個功能規劃了,這個版本還沒實作。因為日志量也比較大,我們規劃是寫到我們地ufile上的。
作者介紹 徐亮
負責ucloud接入網絡的架構設計、開發和營運。擁有15年高可用、大并發和分布式背景開發經驗。
先後任職于上海貝爾、騰訊,從事背景開發工作,項目包括中南海黨政專網呼叫中心、營運商級别的wap/http網際網路網關;騰訊廣告播放系統、微信公衆号開發;hadoop大資料分析、硬體負載均衡器。
目前,主要專注于dpdk開發nfv、sdn以及unikernel虛拟化。
<b></b>
<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2016-03-31</b>