五分鐘看懂抓包神技:DPDK
- 2020 年 11 月 13 日
- 筆記
我是一個網路監控軟體,我被開發出來的使命就是監控網路中進進出出的所有通訊流量。
一直以來,我的工作都非常的出色,但是隨著我監控的網路越來越龐大,網路中的通訊流量也變得越來越多,我開始有些忙不過來了,逐漸發生丟包的現象,而且最近這一現象越發的嚴重了。
萬兆流量需求
一天晚上,程式設計師哥哥把我從硬碟上叫了起來。
「這都幾點了,你怎麼還不下班啊?」,我問小哥哥。
「哎,產品經理說了,讓我下個月必須支援萬兆網路流量的分析,我這壓力可大了,沒辦法只好加班了。」,說完整理了一下自己那日益稀疏的頭髮。
「萬兆?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文章