為何不選擇lunix AIO


對於塊設備而言,linux可以使用同步IO、POSIX IO、linux AIO、io-uring,前倆者是linux的同步IO接口,后者是linux內核提供的異步io接口,linux AIO只支持直接IO,未來趨勢是io-uring。網絡IO多用select/epoll,將其封裝使用起來像異步IO,同步與異步區別在於是否堵塞線程,磁盤性能,同步異步IO都可以壓榨完,對於同步異步的選擇應該看每種IO方式的IO鏈路,以及對數據的拷貝次數,並結合自己場景和需求去分析,可接受應該在應用層改變。

Lunix AIO是否不成熟

glibc 的AIO,采用的是POSIX接口,無論有無bug、調試難度,API中無connect、accept、send、recv,存在的都是文件IO的使用者,數據庫開發者,MySQL 5.6 innodb在lunix下已經使用native AIO實現了,innodb-use-native-aio變量默認開啟。

以nginx 為例,說明nginx僅支持在讀取文件時使用AIO,寫入文件時往往是寫入內存就立刻返回,AIO不支持緩存操作,即使需要操作的文件在linux文件緩存中存在,也不會通過操作緩存中的文件塊來代替實際對磁盤的操作,會降低實際處理能力的性能。

  • 僅支持direct IO 只能使用O-DIRECT,不能借助文件緩存來緩存當前的IO請求,還存在size對齊
  • 仍然可能被阻塞  在系統層上events條件不成立,會進入睡眠
  • 拷貝開銷大 大量小io場景下 拷貝影響比較大
  • API 不友好 submit wait-for-completion 
  • 系統調用開銷大  

io-uring

  • 易用,對其中常用的功能進行了一次封裝,提供了簡單易用的接口liburing
  • 可擴展,支持網絡I/O等非塊設備
  • 高效,減少了每次調度要傳的參數大小,減少系統調用次數,通過一次系統調用提交多個IO請求的方式
  • 可伸縮,用戶態和核心態都支持輪詢,可以在不調用syscall的情況下直接處理IO請求

原理與結構 

  • 原理是讓用戶態進程與內核通過一個共享內存的無鎖環形隊列進行高效交互
  • 共享內存,減少系統調用過程中的參數內存拷貝,將內核態地址空間映射到用戶態的方式,通過用戶態對io-uring fd進行mmap,可以獲得io-uring相關的兩個內核隊列(IO請求,IO完成時間)的用戶態地址,用戶態程序可以直接操作倆個隊列向內核發送IO請求,接收完內核完成IO事件通知,
  • 無鎖環形隊列,單生產者與單消費者的無鎖隊列,來實現用戶態程序與內核對共享內存的高效並發訪問,生產者只修改隊尾指針,消費者只修改隊頭指針,不會相互阻塞。
  • 內存屏障與保序,保證內存操作順序和一致性,1 修改隊列狀態時,保證對隊列元素的寫入已完成,編譯器可以實現,防止編譯器將修改隊列的指令放到隊列元素寫入完成之前,2 讀取隊列狀態時,需要獲取最新寫入和修改的值,保證緩存一致性刷新

輪詢模式

  • io-uring 提供io-uring-enter系統調用接口,用於通知內核IO請求的產生以及等待內核完成的請求,仍然需要反復調用系統調用,進行上下文切換。ioring-setup- iopoll 和 ioring-setup-sqpoll 同時設置,內核線程會同時對io-uring的隊列和設備驅動隊列做輪詢,對請求隊列、完成事件隊列、設備驅動隊列全部使用輪詢模式,達到最優的IO性能,會產生更多的CPU開銷。

調用接口

  • io-uring-setup 創建接口
  • io-uring-enter 通知內核有IO請求待處理,並根據參數等待請求完成
  • io-uring-register 注冊fd和buffer為常用對象,避免內核反復拷貝

具體實現

  • 讓用戶態程序與內核共享內存,並發修改同一數據結構,是一種危險行為,用戶態異常操作內核處理邏輯,可能讓用戶態程序破壞內核機制
  • uring 的head/tail 指針錯誤,會導致內核處理沒有設置過的sqe,sqe是內核預分配過的內存,不會造成內核訪問非法內存地址
  • uring entries被錯誤修改,可能會造成內核異常,在創建io-uring時就已經確定,可以為每個io-uring單獨保存一份用於實際邏輯處理邏輯,而不使用共享內存中的部分。
  • io-uring提供了復雜而強大的異步IO接口,又實現了liburing來屏蔽高級特性帶來的復雜度,通過共享內存與無鎖隊列與內核進行高性能交互,而避免大量的syscall嗲來的性能開銷和限制,可用於加速實時性要求不高的系統調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM