引言
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(R) Xeon(R) 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"-d120$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 的高性能之路。
責任編輯:xj
原文標題:面對疾風吧!io_uring 優化 nginx 實戰演練
文章出處:【微信公眾號:Linuxer】歡迎添加關注!文章轉載請注明出處。
-
Linux
+關注
關注
87文章
11227瀏覽量
208924 -
IO接口
+關注
關注
0文章
30瀏覽量
13395 -
nginx
+關注
關注
0文章
143瀏覽量
12163
原文標題:面對疾風吧!io_uring 優化 nginx 實戰演練
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論