五分鐘看懂抓包神技:DPDK
我是一個網路監控軟體,我被開發出來的使命就是監控網路中進進出出的所有通訊流量。
一直以來,我的工作都非常的出色,但是隨著我監控的網路越來越龐大,網路中的通訊流量也變得越來越多,我開始有些忙不過來了,逐漸發生丟包的現象,而且最近這一現象越發的嚴重了。
萬兆流量需求
一天晚上,程式設計師哥哥把我從硬碟上叫了起來。
“這都幾點了,你怎麼還不下班啊?”,我問小哥哥。
“哎,產品經理說了,讓我下個月必須支援萬兆網路流量的分析,我這壓力可大了,沒辦法只好加班了。”,說完整理了一下自己那日益稀疏的頭髮。
“萬兆?10Gbps?開玩笑呢吧?這是要累死我的節奏啊”
“可不是嗎,可愁死我了。你快給我說說,你工作這麼久了,有沒有乾的不爽的或者覺得可以改進的地方都可以給我說說”,小哥哥真誠的看著我。
我思考了片刻說到:“要說乾的不爽的,還真有!就是我現在花了太多時間在拷貝資料包了,把資料包從核心空間拷貝到使用者態空間,以前資料量小還行,現在網路流量這麼大,可真是要了我的老命了。”
小哥哥嘆了口氣,“哎,這個改不了,資料包是通過作業系統的API獲取的,作業系統又是從網絡卡那裡讀取的,咱們是工作在使用者空間的程式,必須要拷貝一次,這沒辦法。你再想想別的?”
我也嘆了口氣,“那行吧,還有一個槽點,資料包收到後能不能直接交給我,別交給系統的協議棧和netfilter框架他們去處理了,反正我拿來後也要重新分析,每次都從他們那裡過一次,他們辦事效率又低,這不拖累我的工作嘛”
小哥哥皺著眉頭,眨了眨眼睛說到:“大兄弟,這個咱也改不了啊,我這水平也有限,我還沒有能力改造你繞過作業系統讓你直接去跟網絡卡打交道啊。要不,要不你再說一個?嘿嘿”
“好吧,我也就不為難你了。有個簡單的問題,你可得改一下”
“什麼問題,說說看?”
“就是我現在花了很多時間線上程切換上,等到再次獲得排程執行後,經常發現換了一個CPU核,導致之前的快取都失效了,得重新建立快取,這又是一個很大的浪費啊!能不能讓我的工作執行緒獨佔CPU的核心,這樣我肯定能提高不少工作效率!”
小哥哥稍微思考了一下,說到:“沒問題,這個可以有!用執行緒親和性就可以搞定,給你劃幾個核出來,不讓它們參與系統的執行緒排程分配,專門給你用,這事就包在我身上吧!”
中斷問題
過了幾天,程式設計師哥哥對我進行了升級改造,讓我的幾個工作執行緒都能獨佔CPU核,工作效率提升了不少。
不過,距離產品經理要求的萬兆流量分析指標,那還是差了一大截。
一天晚上,程式設計師小哥哥又找我聊了起來。
“現在分析能力確實有所提升,不過離目標還差得遠啊,你快給我說說,還有沒有改進的建議給我啊?”
“有倒是有,但是我估計你還是會說改不了”,我翻了個白眼。
“你先說說看嘛!”
“現在這個資料包是用中斷的形式來通知讀取的,能不能不用中斷,讓我自己去取啊?你是不知道,每次中斷都要儲存上下文,從使用者態切換到核心態,那麼多流量,這開銷大了去了!”,我激動的說到。
小哥哥聽完沉默了。
“看吧,我就說你改不了吧!還是算了吧,趁早給產品經理說這個需求做不了,咱倆都輕鬆自在”
“那不行,這個專案對我非常重要,我還指望通過你來升職加薪,走向人生巔峰呢!”,小哥哥說的很堅定。
“實在不行,那就多找幾臺機器,把我copy幾份過去,軟體不行就靠硬體堆出效能嘛!”,我衝他眨了個眼睛。
“這還用你說,老闆肯定不會同意的”
“那我沒轍了,實話告訴你吧,想要我能處理萬兆網路流量,非得繞開作業系統,我親自去從網絡卡讀取資料包不可,你好好去研究下吧,想升職加薪,怎麼能怕難呢!”,我給小哥哥打了打氣。
小哥哥點了點頭,“你說的是,我一定可以的,給我一點時間”
DPDK
就這樣過了一個多星期,程式設計師小哥哥一直沒再來找過我,也不知道他研究的怎麼樣了。
又過了好幾天,他終於又來了。
“快出來!我找到辦法了,明天就開始改造你!”
我一聽來了興趣,“什麼辦法?你打算怎麼改造我?”
“這個新方案可以解決你之前提出的所有問題,可以讓你直接去跟網絡卡打交道,不用中斷來通知讀取資料包,也不用再把資料包交給系統協議棧和netfilter框架處理,不用再頻繁的在使用者態和核心態反覆切換了!”,小哥哥越說越激動!
“你也太牛了吧,能把這些問題都解決了!你是怎麼做到這些的,什麼原理?”,我好奇的問到。
小哥哥有些不好意思,“我哪有那本事啊,其實這是別人開發的技術,我只是拿來用而已。”
“額,那你都弄清楚它的原理了嗎,別到時候坑我啊!”,我有些不太放心。
“這個你放心,這個技術叫DPDK,是人家Intel開發的技術,靠譜!”
接下來,程式設計師小哥哥給我介紹了這個叫DPDK的技術原理。
有了DPDK,通過作業系統的使用者態模式驅動UIO,我可以在使用者態通過輪詢的方式讀取網絡卡的資料包,再也不用中斷了!
直接在使用者態讀取,再也不用把資料包在核心態空間和使用者態空間搬來搬去。讀到了之後我直接就可以分析,還不用走系統協議棧和netfilter瞎耽誤功夫,簡直完美!
“還不止這些呢!還支援大頁記憶體技術”,小哥哥得意的說到。
“大頁記憶體?這是什麼”
“預設情況下系統不是以4KB大小來管理記憶體頁面的嗎?這個單位太小了,對於咱們伺服器記憶體會有大量的記憶體頁面,為了管理這些頁面,就會有大量的頁表項。CPU裡面進行記憶體地址翻譯的快取TLB大小有限,頁表項太多就會頻繁失效,降低記憶體地址翻譯的速度!”
聽到這裡,我突然明白了:“我知道了,把這個單位調大,管理的記憶體頁面就少了,頁表項數量就少了,TLB就不容易失效,地址翻譯就能更快對不對?”
“沒錯,你猜猜看,調到多大?”,小哥哥故作神祕。
“翻一倍,8KB?”,見小哥哥搖搖頭,我又猜到:“難道是16KB?”
“太保守了,能支援2MB和1GB兩種大小呢!”
“這麼大,厲害了!”
空轉問題
第二天,程式設計師小哥哥開始了對我進行了徹底的重構。
升級後的我試著跑了一下,發現了一個問題:如果資料包不是很多或者沒有資料包的情況下,我的輪詢基本上就挺浪費時間的,一直空轉,由於我獨佔了一個核,這個核的佔用率就一直是100%,不少別的程式都吐槽我,佔著**不**。
於是,程式設計師小哥哥又對我進行了升級,用上了Interrupt DPDK模式:沒有資料包處理時就進入睡眠,改為中斷通知。還可以和其他執行緒共享CPU核,不再獨佔,但是DPDK執行緒會有更高排程優先順序,一旦資料包多了起來,我又變成輪詢模式,可以靈活切換。
程式設計師哥哥連續加了兩個星期的班,經過一番優化升級,我的資料包分析處理能力有了極大的提升。
然而遺憾的是,測試了幾輪,當面臨10Gbps的流量時,我還是有點力不從心,還是差了那麼一點點。
小哥哥有些灰心喪氣,“我不知道該怎麼辦了,你覺得還有什麼哪些地方可以改進嗎?”
“我現在基本滿負荷工作了,應該沒有什麼地方可以改進了。現在唯一有時間喘口氣的地方就是資料競爭的時候了,遇到資料被加了鎖發生執行緒切換歇一歇”
小哥哥思考了幾秒鐘,突然眼睛一亮,高興的說到:“有了!”
還沒來得及問,就把我關閉,下班去了~
到底程式設計師小哥哥又要對我做什麼呢?
往期TOP5文章
那天,我被拉入一個Redis群聊···
CPU明明8個核,網絡卡為啥拼命折騰一號核?
因為一個跨域請求,我差點丟了飯碗
完了!CPU一味求快出事兒了!
雜湊表哪家強?幾大程式語言吵起來了!
&n