使用者空間網路與核心繞過(kernel-bypass;DPDK)
/ DPDK -> dee-pee-dee-KAY /
通常你的程式送出或收到的每一個網路封包都會經過作業系統核心,核心會複製它、跑 TCP/IP 堆疊、管理中斷,並在使用者模式與核心模式之間切換。這既方便又安全,但這些步驟每一個都耗 CPU,而在每秒數千萬封包時,核心本身成了瓶頸。核心繞過網路採取一個激進的步驟:讓應用程式幾乎直接和網路卡對話,在使用者空間做網路、把核心排除在快速路徑之外。
大致的運作方式:像 DPDK(資料平面開發套件)這樣的框架把一張網路介面綁到一個特殊的使用者空間驅動程式上,把網卡的封包緩衝區直接映射進你行程的定址空間,讓你不需系統呼叫、不需核心複製就能讀寫封包。它不等中斷,而是用一個專屬的 CPU 核心在緊湊迴圈裡「輪詢」網卡(忙碌等待),於是封包一落地就被取走、沒有中斷延遲。因為核心的 TCP/IP 堆疊被繞過,你要嘛在其上跑一個使用者空間的 TCP 堆疊、要嘛自己處理原始封包。相關的核心功能如 XDP,讓你在核心接收路徑最早的點上跑小程式,在不完全離開核心的情況下得到類似的加速。
為何重要:核心繞過是最嚴苛的系統——高頻交易、軟體路由器、電信資料平面、頂級負載平衡器——達到 C10M 規模與微秒級延遲的方式,那是通用核心路徑做不到的。誠實的代價很高:你把整個整個 CPU 核心專用於忙碌輪詢(即使閒置也燒到 100%),你失去核心成熟、安全、久經沙場的 TCP/IP 堆疊與工具,網卡被單一應用程式獨佔,而程式碼遠更難撰寫與維運。它是專家工具、而非預設——多數伺服器應該用 epoll/io_uring 並保留核心。
/* DPDK 快速路徑,示意 */ while (running) { uint16_t n = rte_eth_rx_burst(port, 0, bufs, BURST); for (uint16_t i = 0; i < n; i++) process(bufs[i]); } /* 一個核心忙碌輪詢網卡,無系統呼叫、無中斷 */
一個專屬核心空轉著輪詢網卡,並在使用者空間直接處理封包批次——迴圈中沒有核心。
核心繞過以核心的安全性、防護與成熟的 TCP/IP 堆疊換取純粹的速度,而忙碌輪詢會持續燒掉一整個核心。它是用於極端封包速率的小眾工具;對一般的高效能伺服器而言,搭配核心堆疊的 epoll/kqueue/io_uring 才是正確選擇。