(つ`ω´)つ says to Ubuntu 台灣社群
Linux 上 epoll 與 io_uring 的比較 (★ 102 分) 作者以教學專案 TinyGate 反向代理伺服器為起點,說明為何開始研究 Linux 的非同步 I/O(Input/Output,輸入/輸出)機制。第一版 TinyGate 採 worker 架構,雖然能用,但效能和 nginx、HAProxy 這類成熟工具差距很大;第二版改用 epoll 後,效能明顯提升;後來又改寫成 io_uring 架構。文章的核心主張是:epoll 是「就緒模型」,告訴程式某個 I/O 可以做了;io_uring 則是「完成模型」,讓程式提交操作後,由核心在完成時通知結果。 epoll 的主要成本來自大量系統呼叫:註冊檔案描述符後,每次事件通常還需要 `epoll_wait` 加上 `read` 或 `write`,也就是每個 I/O 事件都要多次跨越使用者態與核心態,造成情境切換開銷。io_uring 則使用應用程式與 Linux 核心共用的環狀緩衝區,分成提交佇列與完成佇列;程式把多個操作放入提交佇列,核心完成後再把結果放回完成佇列。一般情況仍需要 `io_uring_enter()` 觸發核心處理,但可以一次提交與回收多個 I/O,若啟用 SQPOLL(Submission Queue Polling,提交佇列輪詢),甚至能在穩定負載下接近零系統呼叫,不過代價是核心執行緒會持續輪詢並消耗 CPU。 文章也提醒,io_uring 不是單純替換 API 就能得到全部好處。真正的零拷貝(zero-copy)需要事先註冊緩衝區,網路傳送可利用 `IORING_OP_SEND_ZC`,但需要較新的核心版本;錯誤也不是以同步系統呼叫的回傳值出現,而是透過 CQE(Completion Queue Event,完成佇列事件)的結果欄位非同步回報。作者最後認為,在 Linux kernel 5.1 以上的現代伺服器上,從零開始的新專案多半應優先考慮 io_uring,而不是再以 epoll 作為主要架構。 Hacker News 討論中,不少人補充 io_uring 的實際採用仍有現實限制。有人指出它曾是高風險攻擊面,常被 seccomp(secure computing mode,Linux 的系統呼叫過濾機制)封鎖,且多次涉及權限提升漏洞,因此像 Go 這類語言執行環境不一定會把它當成安全預設;但也有人補充,近期 Linux 已加入 cBPF(classic Berkeley Packet Filter,可用來限制允許的 io_uring 操作)能力,Red Hat Enterprise Linux 9 與 10 也已預設支援,企業環境的阻力可能正在下降。另有實務經驗指出,某些資料庫伺服器把 Asio 的 epoll 後端換成 io_uring 後 CPU 使用率反而上升,因此評估時不應只看 CPU 百分比,而要比較吞吐量、延遲與滿載時的服務品質。 討論也修正了「io_uring 一定更快」的簡化說法。多位留言者認為,許多非同步框架仍建立在傳統 poll 模型上,若沒有重寫成能善用 io_uring 的操作串接、批次提交與零系統呼叫模式,效能優勢可能有限;也有人指出在大型零拷貝緩衝區上 io_uring 很強,但在某些 POSIX 模擬或簡單輪詢情境中未必勝出。針對 TinyGate 這類反向代理,留言者還建議除了 I/O API 外,也要做 CPU 綁定、每核心一個執行緒、監聽 socket 對齊特定 CPU、善用網卡流量導向,避免跨核心溝通造成快取失效與鎖競爭;換言之,io_uring 是重要工具,但高效能伺服器仍取決於整體架構、記憶體配置、安全政策與網路堆疊調校。 👥 29 則討論、評論 💬 https://news.ycombinator.com/item?id=48613872