概述python
隨着互聯網的高速發展,雲產業的快速突起,基礎架構網絡逐漸偏向基於通用計算平臺或模塊化計算平臺的架構融合,來支持多樣化的網絡功能,傳統的PC機器在分佈式計算平臺上的優點更爲明顯。在這些針對海量數據處理或海量用戶的服務場景,高性能編程顯得尤其重要。linux
全文路線web
- 分析了目前的傳統服務器結構以及可能存在的問題引出需求
- 提出DPDK開發套件如何突破操做系統限制
- 以後分析了dpdk的總體結構
- 最後對相關聯的技術和場景作擴展.
-編程
背景分析緩存
前10年中,網絡程序性能優化的目標主要是爲了解決C10K問題,其研究主要集中在如何管理數萬個客戶端併發鏈接,各類I/O框架下如何進行性能優化,以及操做系統參數的一些優化。當前,解決C10K問題的服務器已經很是多。Nginx和Lighttpd兩款很是優秀的基於事件驅動的web服務框架,Tornado和Django則是基於python開發的非阻塞的web框架這些軟件使得C10K已經再也不是問題了。性能優化
- 從總體上看 爲了知足日益增加的需求主要採用分佈式集羣來分擔負荷,應對大量的用戶請求.
集羣服務器
- 從結構上來看一個節點的服務器框架包含
- 網絡模塊
- 事件驅動模塊
- 隔離,多核業務分發模塊
- 業務層
- 在單個節點上,核的使用來看,主要包括
- 單線程服務器 優勢是無競爭,缺點是沒有充分利用系統資源
- 多進程模型 隔離性好,利用了系統更多的資源,缺點是進程間資源共享難
- 多線程模型 充分利用系統資源,競爭須要當心處理
-網絡
需求分析數據結構
-多線程
DPDK學習路線以及視頻講解+qun720209036獲取
1.dpdk PCI原理與testpmd/l3fwd/skeletion
2.kni數據流程
3.dpdk實現dns
4.dpdk高性能網關實現
5.半虛擬化virtio/vhost的加速
綜合分析
- 在應對網絡密集型的巨大數據量時,通常選擇是橫向擴展節點,可是節點的增多會變相的增長設備成本和技術風險,且當集羣節點到必定的量後,節點之間的交互成本自己就會成爲瓶頸。
- 在特定場合下,譬如嵌入式設備上的後臺服務,服務器不可能搭建集羣。
所以提高服務器自己性能一樣重要。
-
具體分析
傳統服務器可能有下面的潛在問題
- 異步模式的弊端 通常咱們使用epoll來高效的處理網絡讀寫事件。在基於多線程的服務器設計框架中,在沒有請求到來的時候,線程將會休眠,當數據到來時,將由操做系統喚醒對應的線程,也就是說內核須要負責線程間頻繁的上下文切換,咱們是在依靠操做系統調度系統來服務網絡包的調度。在網絡負載很大的場景下只會形成核滿轉且不斷相互切換,進一步增長負荷.那麼就須要回到最原始的方式,使用輪詢方式來完成一切操做,來提高性能。
- 協議棧的擴展性 Linix誕生之初就是爲電話電報控制而設計的,它的控制平面和數據轉發平面沒有分離,不適合處理大規模網絡數據包。而且爲了全面的支持用戶空間的各個功能,協議棧中嵌入了大量用於對接的接口,若是能讓應用程序直接接管網絡數據包處理、內存管理以及CPU調度,那麼性能能夠獲得一個質的提高。爲了達到這個目標,第一個要解決的問題就是繞過Linux內核協議棧,由於Linux內核協議棧性能並非很優秀,若是讓每個數據包都通過Linux協議棧來處理,那將會很是的慢。像Wind River和6 Wind Gate等公司自研的內核協議棧宣稱比Linux UDP/TCP協議棧性能至少提升500%以上,所以能不用Linux協議棧就不用。 不用協議棧的話固然就須要本身寫驅動了,應用程序直接使用驅動的接口來收發報文。PF_RING,Netmap和intelDPDK等能夠幫助你完成這些工做,並不須要咱們本身去花費太多時間。 Intel官方測試文檔給出了一個性能測試數據,在1S Sandbridge-EP 8*2.0GHz cores服務器上進行性能測試,不用內核協議棧在用戶態下吞吐量可高達80Mpps(每一個包處理消耗大約200 cpu clocks),相比之下,使用Linux內核協議棧性能連1Mpps都沒法達到。
- 多核的可擴展性 多核的可擴展性對性能提高也是很是重要的,由於服務器中CPU頻率提高愈來愈慢,納米級工藝改進已是很是困難的事情了,但能夠作的是讓服務器擁有更多的CPU和核心,像國家超級計算中心的天河二號使用了超過3w顆Xeon E5來提升性能。在程序設計過程當中,即便在多核環境下也很快會碰到瓶頸,單純的增長了處理器個數並不能線性提高程序性能,反而會使總體性能愈來愈低。一是由於編寫代碼的質量問題,沒有充分利用多核的並行性,二是服務器軟件和硬件自己的一些特性成爲新的瓶頸,像總線競爭、存儲體公用等諸多影響性能平行擴展的因素。那麼,咱們怎樣才能讓程序能在多個CPU核心上平行擴展:儘可能讓每一個核維護獨立數據結構;使用原子操做來避免衝突;使用無鎖數據結構避免線程間相互等待;設置CPU親緣性,將操做系統和應用進程綁定到特定的內核上,避免CPU資源競爭;在NUMA架構下儘可能避免遠端內存訪問
- 內存的可擴展性 內存的訪問速度永遠也趕不上cache和cpu的頻率,爲了能讓性能平行擴展,最好是少訪問。 從內存消耗來看,若是每一個用戶鏈接佔用2K的內存,10M個用戶將消耗20G內存,而操做系統的三級cache連20M都達不到,這麼多併發鏈接的狀況下必然致使cache失效,從而頻繁的訪問內存來獲取數據。而一次內存訪問大約須要300 cpuclocks,這期間CPU幾乎被空閒。所以減小訪存次數來避免cachemisses是咱們設計的目標。 指針不要隨意指向任意內存地址,由於這樣每一次指針的間接訪問可能會致使屢次cache misses,最好將須要訪問的數據放到一塊兒,方便一次性加載到cache中使用。 按照4K頁來計算,32G的數據須要佔用64M的頁表,使得頁表甚至沒法放到cache中,這樣每次數據訪問可能須要兩次訪問到內存,所以建議使用2M甚至1G的大頁表來解決這個問題。
-
解決方案
- 控制層留給Linux作,其它數據層所有由應用程序來處理。 減小系統調度、系統調用、系統中斷,上下文切換等
- 摒棄Linux內核協議棧,將數據包傳輸到用戶空間定製協議棧
- 使用多核編程技術替代多線程,將OS綁在指定核上運行
- 針對SMP系統,使CPU儘可能使用所在NUMA系統節點的內存,減小內存刷寫
- 使用大頁面,減小訪問
- 採用無鎖技術解競爭
而DPDK剛好爲咱們提供瞭解決問題的腳手架。
-
DPDK
-
概述
Intel® DPDK全稱Intel Data Plane Development Kit,是intel提供的數據平面開發工具集,爲Intel architecture(IA)處理器架構下用戶空間高效的數據包處理提供庫函數和驅動的支持,它不一樣於Linux系統以通用性設計爲目的,而是專一於網絡應用中數據包的高性能處理。目前已經驗證能夠運行在大多數Linux操做系統上,包括FreeBSD 9.二、Fedora release1八、Ubuntu 12.04 LTS、RedHat Enterprise Linux 6.3和Suse EnterpriseLinux 11 SP2等。DPDK使用了BSDLicense,極大的方便了企業在其基礎上來實現本身的協議棧或者應用。 須要強調的是,DPDK應用程序是運行在用戶空間上利用自身提供的數據平面庫來收發數據包,繞過了Linux內核協議棧對數據包處理過程。Linux內核將DPDK應用程序看做是一個普通的用戶態進程,包括它的編譯、鏈接和加載方式和普通程序沒有什麼兩樣。
-
整體結構
主要有如下幾個核心
-
網絡模塊
-
整體分析
DPDK對從內核層到用戶層的網絡流程相對傳統網絡模塊進行了特殊處理,下面對傳統網絡模塊結構和DPDK中的網絡結構作對比
傳統linux網絡層:
硬件中斷--->取包分發至內核線程--->軟件中斷--->內核線程在協議棧中處理包--->處理完畢通知用戶層
用戶層收包-->網絡層--->邏輯層--->業務層
dpdk網絡層:
硬件中斷--->放棄中斷流程
用戶層經過設備映射取包--->進入用戶層協議棧--->邏輯層--->業務層
對比後總結
dpdk優點:
- 減小了中斷次數。
- 減小了內存拷貝次數。
- 繞過了linux的協議棧,進入用戶協議棧,用戶得到了協議棧的控制權,可以定製化協議棧下降複雜度
dpdk劣勢
- 內核棧轉移至用戶層增長了開發成本.
- 低負荷服務器不實用,會形成內核空轉.
-
具體分析
- 攔截中斷,不觸發後續中斷和流程流程,繞過協議棧。 以下所示,經過UIO可以重設內核中終端回調行爲從而繞過協議棧後續的處理流程
trigger
- 無拷貝收發包,減小內存拷貝開銷 如圖所示
- dpdk的包所有在用戶空間使用內存池管理。
- 內核空間與用戶空間的內存交互不用進行拷貝,只作控制權轉移。
packet trans
- 協議棧庫 dpdk爲用戶提供了部分協議處理封裝,使用戶能輕鬆定製化協議棧。
-
內存管理
-
hugepage技術
Linux系統的內存管理依賴於存儲器上,以下所示 Linux在內存管理中採用受保護的虛擬地址模式,在代碼中地址分爲3類:邏輯地址、線性地址、物理地址。程序使用具體內存簡單說就是邏輯地址經過分段機制映射轉化爲線性地址,而後線性地址經過分頁機制映射轉化爲物理地址的過程,而在實際使用中,僅將線性地址映射爲物理地址的過程當中,須要從內存中讀取至少四次頁目錄表(Page Directory)和頁表 (Page Table),爲了加快內核讀取速度,CPU在硬件上對頁表作了緩存,就是TLB。 線性地址先從TLB獲取高速緩存內存,若是不存在就從內存表獲取,若是有直接的映射,直接從內存讀取,沒有則產生缺頁中斷,重新分配物理內存,或者從硬盤上將swap讀取。具體圖示以下:
hupage.jpg
普通頁大小是每一個4K,若是是4K頁的尋址以下,使用物理內存時須要多級查找才能找到對應的內存
page-1.gif
4K的頁表是linux針對通常狀況得出的合適大小,然而對於特殊應用能夠經過擴大頁表面積提升內存使用效率。
dpdk使用hupage的思想就是讓程序儘可能獨佔內存防止內存換出,擴大頁表提升hash命中率,經過hugage技術擴大了該使用的頁表大小,設定爲更適合高頻內存使用程序的狀態,得到了如下幾點優點。
- 無需交換。也就是不存在頁面因爲內存空間不足而存在換入換出的問題
- 減小TLB負載。
- 下降page table查詢負載
-
NUMA
爲了解決單核帶來的CPU性能不足,出現了SMP,但傳統的SMP系統中,全部處理器共享系統總線,當處理器數目愈來愈多時,系統總線競爭加大,系統總線稱爲新的瓶頸。NUMA(非統一內存訪問)技術解決了SMP系統可擴展性問題,已成爲當今高性能服務器的主流體系結構之一。 NUMA系統節點通常是由一組CPU和本地內存組成。NUMA調度器負責將進程在同一節點的CPU間調度,除非負載過高,才遷移到其它節點,但這會致使數據訪問延時增大。下圖是2顆CPU支持NUMA架構的示意圖,每顆CPU物理上有4個核心。
dpdk內存分配上經過proc提供的內存信息,使cpu儘可能使用靠近其所在節點的內存,避免訪問遠程內存影響效率。
numa.png
-
內核管理模塊
Affinity是進程的一個屬性,這個屬性指明瞭進程調度器可以把這個進程調度到哪些CPU上。在Linux中,咱們能夠利用CPU affinity 把一個或多個進程綁定到一個或多個CPU上。CPU Affinity分爲2種,soft affinity和hard affinity。soft affinity僅是一個建議,若是不可避免,調度器仍是會把進程調度到其它的CPU上。hard affinity是調度器必須遵照的規則。爲何須要CPU綁定?
- 增長CPU緩存的命中率 CPU之間是不共享緩存的,若是進程頻繁的在各個CPU間進行切換,須要不斷的使舊CPU的cache失效。若是進程只在某個CPU上執行,則不會出現失效的狀況。在多個線程操做的是相同的數據的狀況下,若是把這些線程調度到一個處理器上,大大的增長了CPU緩存的命中率。可是可能會致使併發性能的下降。若是這些線程是串行的,則沒有這個影響。
- 適合time-sensitive應用在real-time或time-sensitive應用中,咱們能夠把系統進程綁定到某些CPU上,把應用進程綁定到剩餘的CPU上。典型的設置是,把應用綁定到某個CPU上,把其它全部的進程綁定到其它的CPU上。
-
核管理結構
dpdk啓動時會創建會分析系統的邏輯核屬性創建映射表並統一管理,每一個核主要屬性以下.
每一個核屬性包括邏輯核id, 硬核id, numa節點id。dpdk會根據系統默認狀態生成一一綁定的映射表,用戶能夠根據需求更改映射表,後續dpdk框架會根據該映射表進行核綁定。
class core{
lcore_id; //邏輯核id
core_id; //硬核id
socket_id; //NUMA節點id
}
class core coremap[ ] //全部邏輯核的映射表
多核調度框架
- 服務器啓動時選取一個邏輯核作主核
- 而後啓動其餘核作從核
- 全部線程都根據映射表作核綁定
- 控制核主要完成pci,內存,日誌等系統的初始化
- 從核啓動後等待主核初始化完畢後掛載業務處理入口
- 從核運行業務代碼
thread
-
競爭處理
- 多線程在構建服務器時經常要處理競爭問題,dpdk提供了支持多個線程操做的無鎖循環隊列來規避衝突,交換數據。
- 數據包等須要大量重複使用的結構能夠相互隔離,線程持有獨立的可用內存池.
-
性能分析
Seastar是開源的C++框架用於構建在現代硬件上構建高性能的服務器應用。該框架基於DPDK,利用Seastar開發的應用能夠運行在Linux或OSv之上。
下面是seastar的介紹以及利用其開發的內存服務器與其餘服務器的對比,可見dpdk性能相對傳統框架有必定優點,且在網絡密集型的場景下效果很好。
- 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.
性能分析
-
擴展
-
熱更新
DPDK在多線程管理上隔離性至關好,主核和從核經過管道進行命令交互,主核能夠輕鬆的將業務下發給從核,所以能夠很容易的利用這個特色作業務接口熱更新支持。
-
底層轉發
以下圖所示,大部分程序交互時是在傳輸層及以上,但DPDK從二層切入,在構建集羣須要大規模轉發數據時可使用三層轉發,這樣將使數據包轉發下降1層協議棧的開銷.
7層模型