DPDK 分析

概述

隨著互聯(lián)網(wǎng)的高速發(fā)展,云產(chǎn)業(yè)的快速突起,基礎(chǔ)架構(gòu)網(wǎng)絡(luò)逐漸偏向基于通用計(jì)算平臺(tái)或模塊化計(jì)算平臺(tái)的架構(gòu)融合,來支持多樣化的網(wǎng)絡(luò)功能,傳統(tǒng)的PC機(jī)器在分布式計(jì)算平臺(tái)上的優(yōu)勢(shì)更為明顯。在這些針對(duì)海量數(shù)據(jù)處理或海量用戶的服務(wù)場(chǎng)景,高性能編程顯得尤為重要。

全文路線

  • 分析了目前的傳統(tǒng)服務(wù)器結(jié)構(gòu)以及可能存在的問題引出需求
  • 提出DPDK開發(fā)套件如何突破操作系統(tǒng)限制
  • 之后分析了dpdk的整體結(jié)構(gòu)
  • 最后對(duì)相關(guān)聯(lián)的技術(shù)和場(chǎng)景做擴(kuò)展.

背景分析

前10年中,網(wǎng)絡(luò)程序性能優(yōu)化的目標(biāo)主要是為了解決C10K問題,其研究主要集中在如何管理數(shù)萬個(gè)客戶端并發(fā)連接,各種I/O框架下如何進(jìn)行性能優(yōu)化,以及操作系統(tǒng)參數(shù)的一些優(yōu)化。當(dāng)前,解決C10K問題的服務(wù)器已經(jīng)非常多。Nginx和Lighttpd兩款非常優(yōu)秀的基于事件驅(qū)動(dòng)的web服務(wù)框架,Tornado和Django則是基于python開發(fā)的非阻塞的web框架這些軟件使得C10K已經(jīng)不再是問題了。

  • 從整體上看
    為了滿足日益增長(zhǎng)的需求主要采用分布式集群來分擔(dān)負(fù)荷,應(yīng)對(duì)大量的用戶請(qǐng)求.
集群
  • 從結(jié)構(gòu)上來看一個(gè)節(jié)點(diǎn)的服務(wù)器框架包含

  • 網(wǎng)絡(luò)模塊

  • 事件驅(qū)動(dòng)模塊

  • 隔離,多核業(yè)務(wù)分發(fā)模塊

  • 業(yè)務(wù)層

  • 在單個(gè)節(jié)點(diǎn)上,核的使用來看,主要包括

  • 單線程服務(wù)器
    優(yōu)點(diǎn)是無競(jìng)爭(zhēng),缺點(diǎn)是沒有充分利用系統(tǒng)資源

  • 多進(jìn)程模型
    隔離性好,利用了系統(tǒng)更多的資源,缺點(diǎn)是進(jìn)程間資源共享難

  • 多線程模型
    充分利用系用資源,競(jìng)爭(zhēng)需要小心處理

需求分析

綜合分析

  • 在應(yīng)對(duì)網(wǎng)絡(luò)密集型的巨大數(shù)據(jù)量時(shí),一般選擇是橫向擴(kuò)展節(jié)點(diǎn),但是節(jié)點(diǎn)的增多會(huì)變相的增加設(shè)備成本和技術(shù)風(fēng)險(xiǎn),且當(dāng)集群節(jié)點(diǎn)到一定的量后,節(jié)點(diǎn)之間的交互成本本身就會(huì)成為瓶頸。
  • 在特定場(chǎng)合下,譬如嵌入式設(shè)備上的后臺(tái)服務(wù),服務(wù)器不可能搭建集群。

因此提升服務(wù)器本身性能同樣重要。

具體分析

傳統(tǒng)服務(wù)器可能有下面的潛在問題

  • 異步模式的弊端
    一般我們使用epoll來高效的處理網(wǎng)絡(luò)讀寫事件。在基于多線程的服務(wù)器設(shè)計(jì)框架中,在沒有請(qǐng)求到來的時(shí)候,線程將會(huì)休眠,當(dāng)數(shù)據(jù)到來時(shí),將由操作系統(tǒng)喚醒對(duì)應(yīng)的線程,也就是說內(nèi)核需要負(fù)責(zé)線程間頻繁的上下文切換,我們是在依靠操作系統(tǒng)調(diào)度系統(tǒng)來服務(wù)網(wǎng)絡(luò)包的調(diào)度。在網(wǎng)絡(luò)負(fù)載很大的場(chǎng)景下只會(huì)造成核滿轉(zhuǎn)且不斷相互切換,進(jìn)一步增加負(fù)荷.那么就需要回到最原始的方式,使用輪詢方式來完成一切操作,來提升性能。

  • 協(xié)議棧的擴(kuò)展性
    Linix誕生之初就是為電話電報(bào)控制而設(shè)計(jì)的,它的控制平面和數(shù)據(jù)轉(zhuǎn)發(fā)平面沒有分離,不適合處理大規(guī)模網(wǎng)絡(luò)數(shù)據(jù)包。并且為了全面的支持用戶空間的各個(gè)功能,協(xié)議棧中嵌入了大量用于對(duì)接的接口,如果能讓應(yīng)用程序直接接管網(wǎng)絡(luò)數(shù)據(jù)包處理、內(nèi)存管理以及CPU調(diào)度,那么性能可以得到一個(gè)質(zhì)的提升。為了達(dá)到這個(gè)目標(biāo),第一個(gè)要解決的問題就是繞過Linux內(nèi)核協(xié)議棧,因?yàn)長(zhǎng)inux內(nèi)核協(xié)議棧性能并不是很優(yōu)秀,如果讓每一個(gè)數(shù)據(jù)包都經(jīng)過Linux協(xié)議棧來處理,那將會(huì)非常的慢。像Wind River和6 Wind Gate等公司自研的內(nèi)核協(xié)議棧宣稱比Linux UDP/TCP協(xié)議棧性能至少提高500%以上,因此能不用Linux協(xié)議棧就不用。
    不用協(xié)議棧的話當(dāng)然就需要自己寫驅(qū)動(dòng)了,應(yīng)用程序直接使用驅(qū)動(dòng)的接口來收發(fā)報(bào)文。PF_RING,Netmap和intelDPDK等可以幫助你完成這些工作,并不需要我們自己去花費(fèi)太多時(shí)間。
    Intel官方測(cè)試文檔給出了一個(gè)性能測(cè)試數(shù)據(jù),在1S Sandbridge-EP 8*2.0GHz cores服務(wù)器上進(jìn)行性能測(cè)試,不用內(nèi)核協(xié)議棧在用戶態(tài)下吞吐量可高達(dá)80Mpps(每個(gè)包處理消耗大約200 cpu clocks),相比之下,使用Linux內(nèi)核協(xié)議棧性能連1Mpps都無法達(dá)到。

  • 多核的可擴(kuò)展性
    多核的可擴(kuò)展性對(duì)性能提升也是非常重要的,因?yàn)榉?wù)器中CPU頻率提升越來越慢,納米級(jí)工藝改進(jìn)已經(jīng)是非常困難的事情了,但可以做的是讓服務(wù)器擁有更多的CPU和核心,像國家超級(jí)計(jì)算中心的天河二號(hào)使用了超過3w顆Xeon E5來提高性能。在程序設(shè)計(jì)過程中,即使在多核環(huán)境下也很快會(huì)碰到瓶頸,單純的增加了處理器個(gè)數(shù)并不能線性提升程序性能,反而會(huì)使整體性能越來越低。一是因?yàn)榫帉懘a的質(zhì)量問題,沒有充分利用多核的并行性,二是服務(wù)器軟件和硬件本身的一些特性成為新的瓶頸,像總線競(jìng)爭(zhēng)、存儲(chǔ)體公用等諸多影響性能平行擴(kuò)展的因素。那么,我們?cè)鯓硬拍茏尦绦蚰茉诙鄠€(gè)CPU核心上平行擴(kuò)展:盡量讓每個(gè)核維護(hù)獨(dú)立數(shù)據(jù)結(jié)構(gòu);使用原子操作來避免沖突;使用無鎖數(shù)據(jù)結(jié)構(gòu)避免線程間相互等待;設(shè)置CPU親緣性,將操作系統(tǒng)和應(yīng)用進(jìn)程綁定到特定的內(nèi)核上,避免CPU資源競(jìng)爭(zhēng);在NUMA架構(gòu)下盡量避免遠(yuǎn)端內(nèi)存訪問

  • 內(nèi)存的可擴(kuò)展性
    內(nèi)存的訪問速度永遠(yuǎn)也趕不上cache和cpu的頻率,為了能讓性能平行擴(kuò)展,最好是少訪問。
    從內(nèi)存消耗來看,如果每個(gè)用戶連接占用2K的內(nèi)存,10M個(gè)用戶將消耗20G內(nèi)存,而操作系統(tǒng)的三級(jí)cache連20M都達(dá)不到,這么多并發(fā)連接的情況下必然導(dǎo)致cache失效,從而頻繁的訪問內(nèi)存來獲取數(shù)據(jù)。而一次內(nèi)存訪問大約需要300 cpuclocks,這期間CPU幾乎被空閑。因此減少訪存次數(shù)來避免cachemisses是我們?cè)O(shè)計(jì)的目標(biāo)。
    指針不要隨意指向任意內(nèi)存地址,因?yàn)檫@樣每一次指針的間接訪問可能會(huì)導(dǎo)致多次cache misses,最好將需要訪問的數(shù)據(jù)放到一起,方便一次性加載到cache中使用。
    按照4K頁來計(jì)算,32G的數(shù)據(jù)需要占用64M的頁表,使得頁表甚至無法放到cache中,這樣每次數(shù)據(jù)訪問可能需要兩次訪問到內(nèi)存,因此建議使用2M甚至1G的大頁表來解決這個(gè)問題。

解決方案

  • 控制層留給Linux做,其它數(shù)據(jù)層全部由應(yīng)用程序來處理。
    減少系統(tǒng)調(diào)度、系統(tǒng)調(diào)用、系統(tǒng)中斷,上下文切換等
  • 摒棄Linux內(nèi)核協(xié)議棧,將數(shù)據(jù)包傳輸?shù)接脩艨臻g定制協(xié)議棧
  • 使用多核編程技術(shù)替代多線程,將OS綁在指定核上運(yùn)行
  • 針對(duì)SMP系統(tǒng),使CPU盡量使用所在NUMA系統(tǒng)節(jié)點(diǎn)的內(nèi)存,減少內(nèi)存刷寫
  • 使用大頁面,減少訪問
  • 采用無鎖技術(shù)解競(jìng)爭(zhēng)

而DPDK恰好為我們提供了解決問題的腳手架。

DPDK

概述

Intel? DPDK全稱Intel Data Plane Development Kit,是intel提供的數(shù)據(jù)平面開發(fā)工具集,為Intel architecture(IA)處理器架構(gòu)下用戶空間高效的數(shù)據(jù)包處理提供庫函數(shù)和驅(qū)動(dòng)的支持,它不同于Linux系統(tǒng)以通用性設(shè)計(jì)為目的,而是專注于網(wǎng)絡(luò)應(yīng)用中數(shù)據(jù)包的高性能處理。目前已經(jīng)驗(yàn)證可以運(yùn)行在大多數(shù)Linux操作系統(tǒng)上,包括FreeBSD 9.2、Fedora release18、Ubuntu 12.04 LTS、RedHat Enterprise Linux 6.3和Suse EnterpriseLinux 11 SP2等。DPDK使用了BSDLicense,極大的方便了企業(yè)在其基礎(chǔ)上來實(shí)現(xiàn)自己的協(xié)議?;蛘邞?yīng)用。
需要強(qiáng)調(diào)的是,DPDK應(yīng)用程序是運(yùn)行在用戶空間上利用自身提供的數(shù)據(jù)平面庫來收發(fā)數(shù)據(jù)包,繞過了Linux內(nèi)核協(xié)議棧對(duì)數(shù)據(jù)包處理過程。Linux內(nèi)核將DPDK應(yīng)用程序看作是一個(gè)普通的用戶態(tài)進(jìn)程,包括它的編譯、連接和加載方式和普通程序沒有什么兩樣。

總體結(jié)構(gòu)

主要有以下幾個(gè)核心

  • 網(wǎng)絡(luò)層模塊
  • 內(nèi)存管理模塊
  • 內(nèi)核管理模塊

網(wǎng)絡(luò)模塊

總體分析

DPDK對(duì)從內(nèi)核層到用戶層的網(wǎng)絡(luò)流程相對(duì)傳統(tǒng)網(wǎng)絡(luò)模塊進(jìn)行了特殊處理,下面對(duì)傳統(tǒng)網(wǎng)絡(luò)模塊結(jié)構(gòu)和DPDK中的網(wǎng)絡(luò)結(jié)構(gòu)做對(duì)比

傳統(tǒng)linux網(wǎng)絡(luò)層:

硬件中斷--->取包分發(fā)至內(nèi)核線程--->軟件中斷--->內(nèi)核線程在協(xié)議棧中處理包--->處理完畢通知用戶層

用戶層收包-->網(wǎng)絡(luò)層--->邏輯層--->業(yè)務(wù)層

dpdk網(wǎng)絡(luò)層:

硬件中斷--->放棄中斷流程
用戶層通過設(shè)備映射取包--->進(jìn)入用戶層協(xié)議棧--->邏輯層--->業(yè)務(wù)層                                                                                                                                                        

對(duì)比后總結(jié)

dpdk優(yōu)勢(shì):

  • 減少了中斷次數(shù)。
  • 減少了內(nèi)存拷貝次數(shù)。
  • 繞過了linux的協(xié)議棧,進(jìn)入用戶協(xié)議棧,用戶獲得了協(xié)議棧的控制權(quán),能夠定制化協(xié)議棧降低復(fù)雜度

dpdk劣勢(shì)

  • 內(nèi)核棧轉(zhuǎn)移至用戶層增加了開發(fā)成本.
  • 低負(fù)荷服務(wù)器不實(shí)用,會(huì)造成內(nèi)核空轉(zhuǎn).

具體分析

  • 攔截中斷,不觸發(fā)后續(xù)中斷和流程流程,繞過協(xié)議棧。
    如下所示,通過UIO能夠重設(shè)內(nèi)核中終端回調(diào)行為從而繞過協(xié)議棧后續(xù)的處理流程


    trigger
  • 無拷貝收發(fā)包,減少內(nèi)存拷貝開銷
    如圖所示

  • dpdk的包全部在用戶空間使用內(nèi)存池管理。

  • 內(nèi)核空間與用戶空間的內(nèi)存交互不用進(jìn)行拷貝,只做控制權(quán)轉(zhuǎn)移。


    packet trans
  • 協(xié)議棧庫
    dpdk為用戶提供了部分協(xié)議處理封裝,使用戶能輕松定制化協(xié)議棧。

內(nèi)存管理

hugepage技術(shù)

Linux系統(tǒng)的內(nèi)存管理依賴于存儲(chǔ)器山,如下所示
Linux在內(nèi)存管理中采用受保護(hù)的虛擬地址模式,在代碼中地址分為3類:邏輯地址、線性地址、物理地址。程序使用具體內(nèi)存簡(jiǎn)單說就是邏輯地址通過分段機(jī)制映射轉(zhuǎn)化為線性地址,然后線性地址通過分頁機(jī)制映射轉(zhuǎn)化為物理地址的過程,而在實(shí)際使用中,僅將線性地址映射為物理地址的過程中,需要從內(nèi)存中讀取至少四次頁目錄表(Page Directory)和頁表 (Page Table),為了加快內(nèi)核讀取速度,CPU在硬件上對(duì)頁表做了緩存,就是TLB。
線性地址先從TLB獲取高速緩存內(nèi)存,如果不存在就從內(nèi)存表獲取,如果有直接的映射,直接從內(nèi)存讀取,沒有則產(chǎn)生缺頁中斷,從新分配物理內(nèi)存,或者從硬盤上將swap讀取。具體圖示如下:

hupage.jpg

普通頁大小是每個(gè)4K,如果是4K頁的尋址如下,使用物理內(nèi)存時(shí)需要多級(jí)查找才能找到對(duì)應(yīng)的內(nèi)存


page-1.gif

4K的頁表是linux針對(duì)一般情況得出的合適大小,然而對(duì)于特殊應(yīng)用可以通過擴(kuò)大頁表面積提高內(nèi)存使用效率。

dpdk使用hupage的思想就是讓程序盡量獨(dú)占內(nèi)存防止內(nèi)存換出,擴(kuò)大頁表提高h(yuǎn)ash命中率,通過hugage技術(shù)擴(kuò)大了該使用的頁表大小,設(shè)定為更適合高頻內(nèi)存使用程序的狀態(tài),獲得了以下幾點(diǎn)優(yōu)勢(shì)。

  • 無需交換。也就是不存在頁面由于內(nèi)存空間不足而存在換入換出的問題
  • 減少TLB負(fù)載。
  • 降低page table查詢負(fù)載

NUMA

為了解決單核帶來的CPU性能不足,出現(xiàn)了SMP,但傳統(tǒng)的SMP系統(tǒng)中,所有處理器共享系統(tǒng)總線,當(dāng)處理器數(shù)目越來越多時(shí),系統(tǒng)總線競(jìng)爭(zhēng)加大,系統(tǒng)總線稱為新的瓶頸。NUMA(非統(tǒng)一內(nèi)存訪問)技術(shù)解決了SMP系統(tǒng)可擴(kuò)展性問題,已成為當(dāng)今高性能服務(wù)器的主流體系結(jié)構(gòu)之一。
NUMA系統(tǒng)節(jié)點(diǎn)一般是由一組CPU和本地內(nèi)存組成。NUMA調(diào)度器負(fù)責(zé)將進(jìn)程在同一節(jié)點(diǎn)的CPU間調(diào)度,除非負(fù)載太高,才遷移到其它節(jié)點(diǎn),但這會(huì)導(dǎo)致數(shù)據(jù)訪問延時(shí)增大。下圖是2顆CPU支持NUMA架構(gòu)的示意圖,每顆CPU物理上有4個(gè)核心。

dpdk內(nèi)存分配上通過proc提供的內(nèi)存信息,使cpu盡量使用靠近其所在節(jié)點(diǎn)的內(nèi)存,避免訪問遠(yuǎn)程內(nèi)存影響效率。


numa.png

內(nèi)核管理模塊

Affinity是進(jìn)程的一個(gè)屬性,這個(gè)屬性指明了進(jìn)程調(diào)度器能夠把這個(gè)進(jìn)程調(diào)度到哪些CPU上。在Linux中,我們可以利用CPU affinity 把一個(gè)或多個(gè)進(jìn)程綁定到一個(gè)或多個(gè)CPU上。CPU Affinity分為2種,soft affinity和hard affinity。soft affinity僅是一個(gè)建議,如果不可避免,調(diào)度器還是會(huì)把進(jìn)程調(diào)度到其它的CPU上。hard affinity是調(diào)度器必須遵守的規(guī)則。為什么需要CPU綁定?

  • 增加CPU緩存的命中率
    CPU之間是不共享緩存的,如果進(jìn)程頻繁的在各個(gè)CPU間進(jìn)行切換,需要不斷的使舊CPU的cache失效。如果進(jìn)程只在某個(gè)CPU上執(zhí)行,則不會(huì)出現(xiàn)失效的情況。在多個(gè)線程操作的是相同的數(shù)據(jù)的情況下,如果把這些線程調(diào)度到一個(gè)處理器上,大大的增加了CPU緩存的命中率。但是可能會(huì)導(dǎo)致并發(fā)性能的降低。如果這些線程是串行的,則沒有這個(gè)影響。

  • 適合time-sensitive應(yīng)用在real-time或time-sensitive應(yīng)用中,我們可以把系統(tǒng)進(jìn)程綁定到某些CPU上,把應(yīng)用進(jìn)程綁定到剩余的CPU上。典型的設(shè)置是,把應(yīng)用綁定到某個(gè)CPU上,把其它所有的進(jìn)程綁定到其它的CPU上。

核管理結(jié)構(gòu)

dpdk啟動(dòng)時(shí)會(huì)建立會(huì)分析系統(tǒng)的邏輯核屬性建立映射表并統(tǒng)一管理,每個(gè)核主要屬性如下.

每個(gè)核屬性包括邏輯核id, 硬核id, numa節(jié)點(diǎn)id。dpdk會(huì)根據(jù)系統(tǒng)默認(rèn)狀態(tài)生成一一綁定的映射表,用戶可以根據(jù)需求更改映射表,后續(xù)dpdk框架會(huì)根據(jù)該映射表進(jìn)行核綁定。

class core{
    lcore_id;           //邏輯核id
    core_id;            //硬核id
    socket_id;         //NUMA節(jié)點(diǎn)id
}

class core coremap[ ]     //所有邏輯核的映射表

多核調(diào)度框架

  • 服務(wù)器啟動(dòng)時(shí)選取一個(gè)邏輯核做主核
  • 然后啟動(dòng)其他核做從核
  • 所有線程都根據(jù)映射表做核綁定
  • 控制核主要完成pci,內(nèi)存,日志等系統(tǒng)的初始化
  • 從核啟動(dòng)后等待主核初始化完畢后掛載業(yè)務(wù)處理入口
  • 從核運(yùn)行業(yè)務(wù)代碼
thread

競(jìng)爭(zhēng)處理

  • 多線程在構(gòu)建服務(wù)器時(shí)常常要處理競(jìng)爭(zhēng)問題,dpdk提供了支持多個(gè)線程操作的無鎖循環(huán)隊(duì)列來規(guī)避沖突,交換數(shù)據(jù)。
  • 數(shù)據(jù)包等需要大量重復(fù)使用的結(jié)構(gòu)可以相互隔離,線程持有獨(dú)立的可用內(nèi)存池.

性能分析

Seastar是開源的C++框架用于構(gòu)建在現(xiàn)代硬件上構(gòu)建高性能的服務(wù)器應(yīng)用。該框架基于DPDK,利用Seastar開發(fā)的應(yīng)用可以運(yùn)行在LinuxOSv之上。

下面是seastar的介紹以及利用其開發(fā)的內(nèi)存服務(wù)器與其他服務(wù)器的對(duì)比,可見dpdk性能相對(duì)傳統(tǒng)框架有一定優(yōu)勢(shì),且在網(wǎng)絡(luò)密集型的場(chǎng)景下效果很好。

  • Seastar uses a shared-nothing model that shards all requests onto individual cores.
  • Seastar offers a choice of network stack, including conventional Linux networking for ease of development, DPDK for fast user-space networking on Linux, and native networking on OSv.
  • an advanced new model for concurrent applications that offers C++ programmers both high performance and the ability to create comprehensible, testable high-quality code.
  • a design for sharing information between CPU cores without time-consuming locking.
性能分析

擴(kuò)展

熱更新

DPDK在多線程管理上隔離性相當(dāng)好,主核和從核通過管道進(jìn)行命令交互,主核可以輕松的將業(yè)務(wù)下發(fā)給從核,因此可以很容易的利用這個(gè)特點(diǎn)做業(yè)務(wù)接口熱更新支持。

底層轉(zhuǎn)發(fā)

如下圖所示,大部分程序交互時(shí)是在傳輸層及以上,但DPDK從二層切入,在構(gòu)建集群需要大規(guī)模轉(zhuǎn)發(fā)數(shù)據(jù)時(shí)可以使用三層轉(zhuǎn)發(fā),這樣將使數(shù)據(jù)包轉(zhuǎn)發(fā)降低1層協(xié)議棧的開銷.

7層模型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容