目錄
前文列表
《Linux 內核網絡協議棧》
《DPDK 網絡加速在 NFV 中的應用》
內核協議棧存在的意義
關於內核協議棧的功能與原理我們在《Linux 內核網絡協議棧》一文中已有討論,這里我們主要思考內核協議棧存在的意義。要回答這個問題,我希望從操作系統聊起。
一個正在運行的程序會做一件非常簡單的事情:執行指令。CPU 從內存中獲取一條指令,對其進行解碼、然后執行它應該做的事情,例如:相加算數、訪問內存、檢查條件、跳轉到函數等等。
實際上,有一類軟件負責讓這些程序的運行變得簡單,運行程序間共享內存,讓程序能夠與設備交互,這類軟件就是操作系統。現在被我們稱之為 “操作系統” 的軟件其實最早的稱謂是 Supervisor,往后還被叫過一段時間的 Master Control Program(主控程序),但最終 Operating System 勝出了。它們負責確保系統即易於使用又能正確高效的運行,為此,操作系統實現了以下兩點需求:
- 操作系統帶來了硬件的獨立性和容易使用的 API(系統調用),讓上層應用程序的運行更加簡單。
- 操作系統應用(CPU、內存)虛擬化技術添加了一個時間分享的層,讓多個上層應用程序的運行更加簡單。
寫到這里不僅感嘆 Unix 操作系統與 C 語言的出現,以及貝爾實驗室排除萬難使用 C 語言重寫了 Unix 的壯舉。從此,上層應用程序與計算機硬件的世界被解耦,黑客文化與思潮得以誕生,正是這群軟件世界的叛逆者捍衛了代碼的自由,開源運動才得以啟動。
回到主題,從操作系統的啟發,我們大概能夠理解內核協議棧的意義,它是為了讓種類多如繁星的網絡協議能夠在計算機上運行得更加簡單。但世上本不存在所謂的 “萬金油”,計算機的世界從來都是時間與空間的博弈。看似萬能的內核協議棧,其實充滿妥協 —— Linux 內核協議棧存在嚴重的 Scalable(可伸展性)問題。
NOTE:
- BPS(Bit Per Second):比特每秒,表示每秒鍾傳輸多少位信息,即帶寬。例如:常說的 1M 帶寬的意思是 1Mbps(兆比特每秒)。
- CPS(Connect Per Second):TCP 每秒新建連接數。
- PPS(Packet Per Second):包轉發率,即能夠同時轉發的數據包的數量,表示轉發數據包能力的大小。
從上圖可以看見,內核協議棧的 CPS、PPS 以及 CPU 數量的關系遠沒有達到線性提升,甚至遠沒有用戶態協議棧來的優秀。據經驗,在C1(8 Core)上運行應用程序每 1W 包處理需要消耗 1% 軟中斷 CPU,這意味着單機的上限是 100W PPS。假設,要跑滿 10GE 網卡,每個包 64 字節,就需要 2000W PPS(注:實際上以太網萬兆網卡速度上限是 1488W PPS,因為最小數據幀的大小為 84B),100G 就是 2億 PPS,即每個包的處理耗時不能超過 50 納秒。而一次 Cache Miss,不管 Miss 的是 TLB、數據 Cache 還是指令 Cache,回內存讀取都需要大約為 65 納秒,而且在 NUMA 架構體系下的跨 Node 通訊大約還需要額外多加 40 納秒。
所以,內核協議棧一秒鍾能處理的數據包是有限的。當達到上限的時候,所有的 CPU 都開始忙於接收數據包。在這種情形下,數據包要么被丟棄,要么會導致應用 CPU 匱乏( starve of CPU)。誠然,這並非內核協議棧所願,但現實如此,受限於操作系統和硬件設備的實現細節,內核協議棧選擇了向空間(滿足大部分常規使用場景)“妥協”。
對此,筆者曾在《DPDK 網絡加速在 NFV 中的應用》一文中詳細談到 Linux 內核協議棧存在的問題,這里不再贅述,簡單總結為幾點:
- 上下文切換開銷大
- 內存拷貝昂貴
- Cache Miss 高
- 中斷處理頻繁
- 系統調用開銷
再回過頭來看,我們可以明顯的感受到網速一直在提升,網絡技術的發展從 1GE/10GE/25GE/40GE/100GE 演變,這也為計算機網絡 I/O 能力提出了挑戰。如何跟上網速的發展?這是一個寬泛的命題,我們只看其中的一個方法 —— 用戶態網絡協議棧。
用戶態網絡協議棧簡述
用戶態網絡協議棧,即在 Linux 用戶態上實現的網絡協議棧處理程序,底層支撐技術被稱為內核旁路技術,又可細分為完全內核旁路及部分內核旁路。其思路大抵是繞過內核,直接將網絡硬件設備交給運行在用戶態的應用程序使用,常見的內核旁路技術實現有 PF_RING、Snabbswitch、Netmap 以及 DPDK。
有了內核旁路技術,開發者得以編寫自己的網絡協議棧,讓協議棧功能變得更加靈活,專注於某些高級特性,並且針對性能進行優化。可見,用戶態網絡協議棧最大的特點就是 “自定義”,針對特定的業務需求來實現數據流量轉發控制以及性能提升。當然了,這也需要付出代價 —— 每一張網卡只能用於一個進程,此時的網卡不再具備 “常規意義上” 的網卡功能。例如:Linux 的 netstat、tcpdump 等工具可能會停止工作。
對於部分內核旁路技術,內核仍然保留對網卡的擁有權,並且能讓用戶態應用程序只在一個單獨的接收隊列(Rx Queue)上執行旁路,典型的部分內核旁路技術實現有 Linux 社區開源的 Netmap,官方數據是 10G 網卡 1400W PPS,已經比較接近 1488W 的極限了,但是 Netmap 沒又得到廣泛使用。其原因有幾個:
- Netmap 需要網卡驅動的支持,即受制於網卡廠商。
- Netmap 仍然依賴中斷通知機制,沒完全解決瓶頸。
- Netmap 更像是幾個系統調用,實現用戶態直接收發包,功能太過原始,沒形成依賴的網絡開發框架,社區不完善。
但鑒於目前還沒有穩定的開源部分內核旁路技術方案,我們希望 Netmap 能搶占這個商機。畢竟現在常見的 DPDK 與 Intel 的關系實在過於緊密。
用戶態網絡協議棧的應用場景:
- 軟件定義的交換機或者路由器,例如 OvS、vRouter。該場景中希望將網卡交由應用程序來管理,以及處理原始的數據包並且完全繞開內核。
- 專用的負載均衡器。類似的,如果該機器只用來做數據包的隨機處理(Packet Shuffling),那繞過內核就是合理的。
- 對於選定的高吞吐/低延遲的應用進行部分旁路。例如:DDoS 緩解系統中。
- 在高頻交易(High Frequency Trading)場景中使用,因為用戶態協議可以很好的降低延遲。
用戶態網絡協議棧面臨的挑戰:
- Linux 內核協議棧有很多重要的特性和優秀的調試能力。需要花費長期的時間才可能挑戰這個豐富的生態系統。
用戶態協議棧如何解決這個問題?
解決問題,首先要提出問題。這里的問題是:如何提高收包吞吐?
以 DPDK 為例,筆者《DPDK 網絡加速在 NFV 中的應用》一文中也有過闡述,這里不再贅述。
參考文檔
https://www.cnblogs.com/huangfuyuan/p/9238437.html
https://cloud.tencent.com/developer/article/1198333
https://blog.csdn.net/dog250/article/details/80532754