隨着京東業務的高速增加,做爲應用入口的負載均衡,大流量大併發帶來的挑戰愈來愈嚴峻。本文主要介紹了京東商城設計和實踐的一套高可靠,高性能的負載均衡器,咱們命名爲SKYLB。是一個使用intel DPDK報文轉發庫,實現運行在通用X86服務器上自研的分佈式負載均衡服務。配合網絡路由器的OSPF或者BGP協議,組成承擔京東數據中心核心四層負載均衡的集羣。最大限度的發揮普通X86服務器硬件資源的性能,實現一套適合於京東商城業務的低成本,分佈式,高性能,可擴展的智能負載均衡系統。前端
京東商城目前是國內最大的電商企業。京東的機房內部的流量爆炸式快速的增加。早在2016年初京東商城已經將全部的業務系統所有遷移到容器平臺JDOS,線上百萬+容器實例穩定運行。大流量的負載均衡的分配顯得相當重要,也是京東商城新一代軟件定義數據中心的關鍵基礎服務設施之一。git
負載均衡器通常介於網絡上的路由器與後端服務器之間,負責將每一個數據包經過必定的服務匹配,將其轉發到後端服務器節點。充分考慮到京東商城數據中心全容器及全三層BGP組網的模型。以及基於DPDK的幾乎達到網卡限速的性能,咱們在設計負載均衡時,僅考慮實現了FULLNAT模式,即出向和入向的流量均經過負載均衡器,基本數據流程圖以下圖1所示:github
通常根據業務及流量的規模的不一樣階段來選擇使用不一樣的負載均衡,一般咱們在負載均衡的選擇上大體有如下兩個方向:1)硬件負載均衡,如F5。CitrixNetscaler等;2)軟件負載均衡,如基於LVS,Haproxy,Nginx等開源軟件來實現的負載均衡。對於上述兩種負載均衡的選擇,各有優缺點,以下:算法
1)硬件負載均衡編程
可擴展性受限,沒法跟上業務流量增加的需求。以及如61八、雙十一大促等瞬間流量高峯。後端
雖然能夠成對部署避免單點故障,可是通常只能提供1+1冗餘。api
缺少互聯網快速迭代的靈活性,升級成本昂貴。安全
通常只能根據網絡的狀況來設定負載均衡,無關乎實際系統和硬件的狀況。性能優化
成本較高。服務器
2)基於開源軟件的負載均衡
能夠根據實際系統和應用的狀態來合理的負載,迭代、擴容和部署相對方便。
單臺負載均衡性能相對較差,須要用集羣來支撐負載均衡的總體性能。
性價比較低。
咱們的目標:
本文主要介紹了SKYLB一種基於DPDK平臺實現的快速可靠的軟件網絡負載均衡系統。不只能夠快速的橫向擴展,還能夠最大限度的提高負載均衡單個NIC的處理轉發速度,來實現L4的負載均衡。藉助DPDK的優點,如便利的多核編程框架、巨頁內存管理、無鎖隊列、無中斷poll-mode 網卡驅動、CPU親和性等等來實現快速的網卡收發及處理報文,後續考慮TCP/IP 用戶態協議實現和優化,進而實現L7負載均衡。
工做場景
SKYLB部署在京東容器集羣JDOS的前端,對於一個應用集羣,發佈一個或多個VIP到SKYLB服務上,當客戶端須要訪問應用節資源URL,首先經過域名訪問JD智能分佈式DNS服務(SKYDNS詳見https://github.com/ipdcode/sk...), SkyDns會智能返回當前最近且狀態正常且負載正常的VIP服務的IP,客戶端就會向VIP去請求鏈接。
SKYLB節點上運行了一個路由發佈服務agent,咱們使用該agent與開啓OSPF/BGP的路由器作路由交互,當SKYLB的上層路由器接收到請求VIP的數據包時,路由器經過(OSPF/BGP)的等價多路徑轉發協議選擇一個可使用的發佈該VIP的SKYLB節點,將報文轉發給一個SKYLB節點。經過這種策略來實現VIP的發佈和橫向容量負載能力擴展。
當報文經過上述步驟到達SKYLB負載均衡後,經過經常使用的負載均衡策略(round robin,一致性hash ,最小鏈接數),將數據包送到相應的後端容器服務。
系統架構
JingdongDatacenter Operating System(JDOS) 是基於JDOS提供物理機/虛擬機/容器的統一管理系統、配備靈活的網絡互連、可靠的分佈式共享存儲,實現軟件定義數據中心的計算資源統一管理和集羣管理。經過使用JDOS,能夠直接迅速獲得任意須要的計算、存儲、網絡、安全等方面的資源和能力。SKYLB做爲整個JDOS系統的一個重要組成部分,負責提供集羣的L4負載均衡能力,經過restful API等接口與JDOS系統交互。用戶能夠經過統一調度管理平臺便捷的建立、刪除、遷移負載均衡系統。同時多個應用服務進行流量分發的負載均衡服務,從而擴展應用系統對外的服務能力,而且經過消除單點故障提升應用系統的可用性。
系統的基本架構以下圖2所示,每個集羣配備一組可容災的負載均衡控制中心,主要經過restful api接口負責與JDOS調度中心交互,接收vip的配置請求。同時咱們在每個SKYLB的節點上運行一個代理進程,該代理進程經過gRPC與控制中心鏈接。接收控制中心下達的建立及刪除vip,後端server endpoint服務等一系列指令,經過load balancer 提供的命令行執行相應的指令。接收load balancer 關於流量及報文的監控信息,對於流量及監控進行告警,而且通知控制中心和調度中心進行擴容等操做。
代理進程同時還負責後端服務 server endpoint基於服務可用性的健康檢查,及時根據後端服務的狀態經過命令行進行添加和刪除的操做。
優點
1)擴展性
支持動態添加和刪除後端服務的容器,實現無縫的伸縮;在伸,縮過程當中,對相關調用和訪問者無影響。
2)高可用性
提供多活負載均衡,有多個VIP,它們對應一個域名,自研DNS服務SKYDNS會根據請求的客戶端IP智能解析可用的VIP,返回給用戶,從而實現更高的可用性;即便一個VIP不可用,也不會影響業務系統對外提供服務。同時藉助OSPF/BGP等協議實現負載均衡的橫向擴充
3)服務能力自動可調
SKYLB根據VIP實際接收流量的負載須要調整負載均衡的服務能力,好比流量、鏈接數的控制等指標。
功能特色
1)協議支持
負載均衡支持包含TCP、UDP協議的四層負載均衡,配備健全的鏈路跟蹤機制,以及多種調度策略,用戶能夠根據服務的須要建立合適本身的負載均衡。
2)高可用性
支持容器的健康檢查,除傳統的IP+Port,並加入對URL檢查,保證應用可用性: 健康檢查頻率可自定義;一旦探測到異常,則不會將流量再分配到這些異常實例,保證應用可用性。
3)集羣部署,多層次容錯機制: 負載均衡採用集羣部署,支持熱升級,機器故障和集羣維護對用戶徹底透明,結合DNS使用還可支持全局負載均衡。
4)靈活性
在此我向你們推薦一個架構學習交流羣。交流學習羣號:948368769裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
支持多種流量調度算法,使得流量分配更均勻: 負載均衡支持加權輪詢和最小鏈接數這兩種調度算法,可根據自身需求選擇相應的算法來分配用戶訪問流量,並支持設置後端容器權重,使得流量調度更均勻,提高負載均衡能力。
支持會話保持,知足用戶個性化需求: 負載均衡經過IP地址實現會話保持,可將必定時間內來自同一用戶的訪問請求,轉發到同一個後端容器上進行處理,從而實現用戶訪問的連續性。
5)易用性
提供多種管理途徑,輕鬆操縱負載均衡: 用戶可經過控制檯輕鬆實現負載均衡器的配置、釋放等功能。後續會開放標準的API或SDK提供給用戶,從而本身開發對負載均衡的控制管理。
負載均衡模式選擇
經常使用的負載均衡模式有DR,NAT,TUNNEL,FULLNAT。每種模式都有本身的優點和使用場景,業內對每種模式的分析比較文檔不少,再也不介紹。因爲JDOS容器網絡須要VLAN隔離,而FULLNAT恰好支持LB和RS跨VLAN通訊,結合咱們自身容器集羣的需求,咱們在實現SKYLB時主要考慮支持FULLNAT模式。圖3是SKYLB的FULLNAT負載均衡模式中數據包的流向圖。SKYLB位於客戶端和後端服務之間,對於客戶端的請求報文,將目的地址替換成後端服務的地址,源地址替換成SKYLB的本地地址,對於後端服務的響應報文,將目的地址替換成客戶端地址,源地址替換成SKYLB的VIP地址。
Data Plane DevelopmentKit(DPDK):是運行在Linux 用戶態,實現X86通用平臺網絡報文快速處理的庫和驅動的集合,以下圖4所示,其主要特色:
多核編程框架及CPU親和性
每一個NUMA節點有單獨的CPU和本地內存
CPU訪問本地內存速度比訪問遠端內存快,避免CPU訪問遠端內存
注意網卡掛載的NUMA節點巨頁內存管理
巨頁(HugePage)
普通內存頁面大小4KB,巨頁內存頁面大小2MB/1GB
減小頁表項數目,下降TLB miss
使用大頁面比使用4K的頁面性能提升10%~15%
零拷貝,報文數據及轉發內存零拷貝。
無鎖隊列
使用無鎖隊列,入隊出隊無需阻塞等待鎖資源
poll-mode網卡驅動
DPDK網卡驅動徹底拋棄中斷模式,基於輪詢方式收包
圖5是SKYLB基於RTC數據包處理模型實現的架構。SKYLB選擇一個核做爲控制核,執行命令配置,與內核交換,ARP表維護等任務。其餘的核做爲工做核,每一個工做核輪詢網卡的一個RX隊列,執行數據包處理任務。SKYLB利用網卡的RSS功能實現客戶端請求報文的分流,利用網卡FDIR功能實現後端服務響應報文的分流。SKYLB對報文分流目的是要保證客戶端的請求報文和其對應的服務端響應報文到達同一個工做核上。在這個目的達成的前提下,SKYLB的業務實現會簡單和高效不少。每一個工做核維護一張session表,同於保存客戶端和後端服務的鏈接信息。SKYLB不須要考慮對session表加鎖,由於每一個工做核的session表都是獨立的。
咱們設計SKYLB每一個工做核獨佔至少一個LIP,並將LIP信息寫入網卡配置。圖6是網卡對IP報文分流的流程圖。圖中dst_ip即SKYLB爲每一個工做核分配的LIP。網卡對後端服務響應報文的目的地址LIP匹配成功,將報文送到綁定的RX隊列,沒有匹配的報文則能夠認爲是客戶端的請求報文,按RSS流程分配RX隊列。
SKYLB在啓動過程當中還會爲每一個物理口建立一個KNI接口,控制核負責輪詢KNI接口。該接口主要用於外部程序quagga向路由器發佈VIP信息,Agent檢查後端服務健康狀態。
SKYLB目前支持的負載均衡調度算法有一致性hash,round robin和最小鏈接數算法。
Session五元組,SKYLB採用五元組來實現會話的管理功能,以下圖7 所示:
SKYLB使用BGP或者OSPF的模式組成集羣,經過上述協議將數據包散列到集羣中各個節點上,保證單臺SKYLB故障或者恢復後能動態的將機器添加及刪除。其冗餘實現設計以下圖6所示:
良好的流程設計是性能提高的關鍵,這方面的流程涉及和業務相關,缺少共性,所以不作詳細闡述。主要介紹SKYLB性能優化過程當中使用的其餘優化方法。
恰當地使用rte_prefetch0(),能夠減小cache-miss次數,避免當前函數成爲性能熱點。性能調優工具perf能夠幫助咱們分析應該在哪處代碼使用預取。例如咱們使用perf發現報文處理函數中有一個處代碼是性能熱點,該代碼用於讀取新報文的類型字段並判斷,分析認爲極可能是cache-misses形成的。在進入報文處理函數前使用rte_prefetch0(),有效避免該函數成爲熱點。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:948368769裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
恰當地使用likely()和unlikely(),能夠減小分支預測失敗的次數。咱們在SKYLB代碼的一處分支語句中使用unlikely()優化,性能提高明顯。分支預測優化點能夠藉助perf分析肯定,也能夠根據本身對代碼執行流程的理解肯定。
儘可能減小鎖的使用。SKYLB中配置信息不常常變化,咱們沒有單獨爲每一個可能爭用的資源加鎖,而是隻用一把DPDK提供的讀寫鎖,每一個讀線程在加讀鎖後,處理一批報文,而後釋放讀鎖。既簡化流程,又減小了操做讀寫鎖的開銷(DPDK讀寫鎖的開銷並非很大)。
測試環境:
CPU:Intel(R) Xeon(R) CPU E5-2640 v3
NIC:intel 82599ES 10-GigabitSFI/SFP+ Network Connection
測試配置:
負載均衡模式:FULLNAT
調度算法:一致性hash
配置:CPU佔用8核 內存佔用4G
性能測試數據:
1)UDP發包,測試轉發性能,咱們使用了SKYDNS做爲後端服務,客戶端採用UDP請求DNS
2)NGINX做爲後端服務,壓測HTTP性能。
配置:CPU佔用8核 內存佔用4G
本文主要介紹了SKYLB,一種的基於intel DPDK平臺開發的負載均衡器。其接近網卡線速處理及轉發能力,靈活的部署,多樣的監控以及可靠的穩定性。基本上覆蓋全部4層負載均衡的業務處理需求,配合集羣管理以及調度,做爲京東數據中心操做系統(JDOS)的一個重要的組成部分,在京東數據中心發揮相當重要的做用。