面對疾風吧!io_uring 優化 nginx 實戰演練
作者:玖一(雲巔論劍)
引言
io_uring是Linux核心在v5.1引入的一套非同步IO介面,隨著其迅速發展,現在的io_uring已經遠遠超過了純IO的範疇。從Linux v5.3版本開始,io_uring陸續新增了網路程式設計相關的API,對使用者提供sendmsg、recvmsg、accept、connect等介面的非同步支援,將io_uring的生態範圍擴大到了網路領域。
另外從Linux v5.7開始,io_uring對這些非同步介面提供FAST POLL機制,使用者無需再使用像select、event poll等多路複用機制來監聽檔案控制程式碼,只要把讀寫請求直接丟到io_uring的submit queue中並提交,當檔案控制程式碼不可讀寫時,核心會主動新增poll handler,當檔案控制程式碼可讀寫時主動呼叫poll handler再次下發讀寫請求,從而減少系統呼叫次數提高效能。
上一篇我們初探了 io_uring 用於網路的程式設計模型以及 echo server benchmark 下的效能表現,這篇文章我們將基於通用應用 nginx 實戰。
Nginx io_uring 程式碼優化
Nginx是一款輕量級的Web伺服器、反向代理伺服器,由於它的記憶體佔用少,啟動極快,高併發能力強,在網際網路專案中廣泛應用。
從架構上看,Nginx由一個master和多個worker程式組成,多個worker之間不需要加鎖,獨立處理與client的連線和網路請求。worker是一個單執行緒大迴圈,這與上一篇“你認為 io_uring 只適用於儲存 IO?大錯特錯!”文章中描述的 echo server 模型基本一致。
基於event poll的程式設計模型
event poll是Nginx在Linux下的預設事件模型。
event poll事件模型把listen fd以及新建連線的sock fd都註冊進event poll中,當這些fd上有資料可讀時,等待在epoll_wait()的worker程式會被喚醒,呼叫相應的回撥函式進行處理,這裡的recv、writev請求都為同步請求。
基於io_uring的程式設計模型
前面提到,io_uring的FAST POLL機制允許資料在未ready的情況下就直接下發,不需要再把普通連線的fd註冊進event poll。另外這裡的讀寫請求通過io_uring非同步下發,處理流程大致如下:
事實上,accept()也可以採取FAFST POLL機制,無需等待listen_fd資料可讀就直接下發,以減少系統呼叫次數。但在除錯過程中發現這樣accept()失敗概率大大增加,而每次失敗的accept()都會帶來一次無效的sock記憶體申請和釋放,這個開銷較大,因此依然採用類似event poll的方式來偵聽listen fd。後續針對這塊可以做一些優化。
測試結果
測試環境
-
測試機器
CPU: Intel® Xeon® CPU E5-2682 v4 @ 2.50GHz 64邏輯核
server cmdline新增:mitigation=on -
nginx配置
user root;
http {
access_log off;
server {
access_log off; // 關閉access log,否則會寫日誌,影響測試
location / {
return 200; // 不讀本地檔案,直接返回200
}
}
}
-
benchmark
使用輕量級HTTP效能測試工具wrk進行壓測。 -
測試命令
長連線 wrk -c $connection -t $thread -d 120 $url
短連線 wrk -c $connection -t $thread -H "Connection: Close" -d 120 $url
測試結果
長連線
- connection=1000,thread=200, 測試server上不同worker數目效能。
worker數目在8以下時,QPS有20%左右的提升。隨著worker數目增大,CPU不成為瓶頸,收益逐漸降低。
- server單worker,測試client端不同連線數效能(thread取預設數2)。
可以看到單worker情況下,500個連線以上,QPS有20%以上的提升。從系統呼叫數目上看,io uring的系統呼叫數基本上在event poll的1/10以內。
短連線
- connection=1000,thread=200, 測試server上不同worker數目效能。
短連線場景,io uring相對於event poll非但沒有提升,甚至在某些場景下有5%~10%的效能下降。究其原因,除了io uring框架本身帶來的開銷以外,還可能跟io uring程式設計模式下請求批量下發而帶來的延遲有關。
總結及下一步工作
從筆者目前的測試來看,io_uring在網路程式設計方面的優化更適合長連線場景,在長連線場景下最高有20%多的提升。短連線場景還有待優化,主要考慮以下兩方面:
- io uring本身框架開銷的優化,當然這個優化對長連線同樣適用。
- 針對短連線的優化,如針對accept()請求,先檢查是否有資料可讀,避免無效記憶體申請釋放;多個accept()一起下發等。
nginx 和 echo server 等優化實踐相關內容(包含原始碼),我們都已經在 OpenAnolis 社群高效能儲存 SIG 開源(openanolis.org)。也歡迎大家積極參與討論和貢獻,一起探索 io_uring 的高效能之路。
歡迎釘釘掃碼入群交流!
相關文章
- 面對疾風吧!今年遊戲代言廣告花樣又翻新了遊戲
- 面對疾風吧,如何搭建高協同的精準告警體系?
- Gin實戰演練
- iOS 元件化 使用cocoapods整合實戰演練iOS元件化
- 實戰 nginx 調優Nginx
- 【實戰分享】又拍雲 OpenResty / Nginx 服務優化實踐RESTNginx優化
- [實戰演練]python3使用requests模組爬取頁面內容Python
- 容災演練,一鍵切換,浙大二院實戰演練圓滿成功!
- WinForm企業級框架實戰專案演練ORM框架
- Known框架實戰演練——進銷存框架搭建框架
- Known框架實戰演練——進銷存系統需求框架
- Known框架實戰演練——進銷存財務管理框架
- 攻防演練 | 實戰加分,安芯網盾實時幫您輕鬆應對哥斯拉Webshell魔改Webshell
- 360推出國家級攻防演習實戰演練服務大禮包 35個優惠名額先報先得
- 實戰演練丨SCN太大引發ORA-600[2252]
- Known框架實戰演練——進銷存資料結構框架資料結構
- Known框架實戰演練——進銷存基礎資料框架
- Known框架實戰演練——進銷存業務單據框架
- 混沌演練實踐(一)
- MySQL——索引優化實戰MySql索引優化
- [.NET專案實戰] Elsa開源工作流元件應用(三):實戰演練元件
- Nginx 軟體層面加強Nginx效能優化的面試問答和解決方案Nginx優化面試
- 實戰NginxNginx
- 23_圖解partial update實現原理以及動手實戰演練圖解
- 對線面試官,憑藉nginx能一戰封神嗎?面試Nginx
- mpvue效能優化實戰技巧Vue優化
- Golang 微服務優化實戰Golang微服務優化
- MySQL 優化實戰記錄MySql優化
- webpack優化之HappyPack 實戰Web優化APP
- Linux效能優化實戰(一)Linux優化
- Linux效能優化實戰(二)Linux優化
- nginx對listen埠的優化 -- 第一篇Nginx優化
- 人工智慧入門與實戰 使用Raspberry Pi和Python演練人工智慧Python
- 26_上機動手實戰演練mget批次查詢apiAPI
- 記某次攻防演練:大戰UEditor並突破
- nginx的location優化Nginx優化
- Nginx 優化及原理Nginx優化
- 實時數倉混沌演練實踐