回憶一下
我們都知道Linux的IO模型有阻塞、非阻塞、SIGIO、多路復用(select,epoll)、AIO(異步I/O)等。
數據庫可能比較傾向于使用AIO。從時序上面來講,AIO是用戶應用發起IO請求io_submit()后,它就不需要去等待,讓后臺給它搞定讀寫。之后本線程或者其他線程就可以通過io_getevents()去同步I/O的結果。
這樣的AIO有一個極大的好處在于,IO不會阻塞住CPU的行為,有利于充分利用硬件的資源,有利于讓CPU、IO都parallel起來 。當然,同樣的動作,似乎用epoll()、SIGIO也可以呈現出來。尤其是epoll(),幾乎是C10K問題解決方案在Linux的代名詞。epoll_wait()先等待IO請求的read、write可以發生,而后再根據返回的事件發起讀寫請求:
事件驅動模型libevent等,看起來是事件到來,callback被執行的Reactor模式:
但是其底層其實也是靠epoll()來實現,這個我們透過strace就可以看出。請見我的3分鐘小電影:
大不一樣
epoll()本質上其實還是先等待IO的讀寫可以發生,而后再以Linux常規read()、write() API去發起IO請求。而AIO則是不管三七二十一,直接發IO請求,但是并不等待這個請求的結束,讓Linux后臺自己去完成讀寫。我們來看一個典型的AIO編程案例:
它是通過io_submit()把IO請求發出去之后,它并不需要等IO的結束。后面用io_getevents()去同步。上面的代碼中,io_getevents()的代碼與io_submit()的代碼擺在一起,但是其實它們并不需要一定是同一個線程。
AIO和傳統epoll()的本質區別是,epoll()等方式,它只是一個事件獲取機制,獲取事件后,之后的read(), write()還是要走Linux的傳統路線,經過Linux內核本身的各個層次(如page cache,IO調度等)。而AIO是骨子里面,自己就是一個IO的方式,最終沒有經過傳統的Linux read(),write()這種"all is file"的類VFS接口。Linux native的AIO本身call的函數,本身就是系統調用。strace執行AIO動作的進程得到的直接就是類似如下的結果:
strace ./aio....
...
io_setup(128, {3077799936}) = 0
io_submit(3077799936, 1, 0xbfa5e730) = 1
io_getevents(-1217167360, 1, 1, {...}NULL) = 1
在ARM Linux的系統調用表里也可以看出:
故而,AIO可以更多地把機會交給用戶空間,讓用戶空間根據自身的IO特點來為自己量身定制IO的行為。AIO一般也直接結合DIO(direct IO)來使用,進一步繞開內核本身的IO調度和cache機制。
我中意你
那么AIO有什么可能的優勢被數據庫所青睞呢?
1. 透過AIO,可以屏蔽掉Linux內核底層的page cache。而制定application-level的cache機制。
我們都知道,Linux會針對每個文件對應的inode,創立一個address_space,并以Radix樹來組織它的page cache命中情況,page的替換算法,整體是LRU,預測頁面本身的活躍度。這個策略,固然非常符合局部性原理(Locality),但是不能針對用戶程序本身的特征,進行用戶級的cache。
2.透過AIO(尤其是結合DIO),可以一定程度上,進行用戶級別的IO scheduling。采用AIO,用戶可以控制發送給內核的IO請求,從而控制誰比誰更重要。內核固然有它的IO調度算法,但是它是比較general的。
3. 透過AIO,可以進行用戶級別的read-ahead和write-behind控制。
我們都知道,Linux內核本身會根據用戶的讀請求,去預測后續的讀,從而在后續的讀還沒有發起的情況下,就提前預讀。詳見:《宋寶華: 文件讀寫(BIO)波瀾壯闊的一生》,但是這種預讀的page,并不一定是上層應用想要的page。而內核的write-behind機制,也可能導致內核累積到很多dirty數據后,出現寫磁盤的突發性洪泛。現在AIO機制,我們把這些都交給用戶。
4. 透過AIO,不阻塞地在前臺線程,直接dispatch IO請求,帶來很好的
scalability。在InnoDB里面,可以透過innodb_use_native_aio來配置使用同步的IO還是AIO,而且它有一番對比,值得細細地品讀。同步IO的時候,query threads是將IO請求放入queue,由InnoDB后臺線程的每個線程處理一個IO請求。而AIO的時候,query threads直接發IO請求。
With synchronous I/O, query threads queue I/O requests, andInnoDBbackground threads retrieve the queued requests one at a time, issuing a synchronous I/O call for each. When an I/O request is completed and the I/O call returns, the InnoDBbackground thread that is handling the request calls an I/O completion routine and returns to process the next request. The number of requests that can be processed in parallel isn, wherenis the number ofInnoDBbackground threads. The number ofInnoDBbackground threads is controlled byinnodb_read_io_threadsand innodb_write_io_threads.
With native AIO, query threads dispatch I/O requests directly to the operating system, thereby removing the limit imposed by the number of background threads.InnoDBbackground threads wait for I/O events to signal completed requests. When a request is completed, a background thread calls an I/O completion routine and resumes waiting for I/O events.
-
cpu
+關注
關注
68文章
10911瀏覽量
213146 -
Linux
+關注
關注
87文章
11351瀏覽量
210507 -
數據庫
+關注
關注
7文章
3852瀏覽量
64738
原文標題:今年是“異型屏”轉換年!華映看好手機市場Q4復蘇
文章出處:【微信號:zengshouji,微信公眾號:MCA手機聯盟】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
Linux設備驅動中的異步通知與異步I/O
Android如何使用Db4o數據庫
Java I/O 的相關方法分析
![Java <b class='flag-5'>I</b>/<b class='flag-5'>O</b> 的相關方法分析](https://file.elecfans.com/web2/M00/49/E0/pYYBAGKhvG6Afar7AAAInv9HNtM799.png)
Linux教程之linux下如何備份還原mysql數據庫
數據庫學習教程之數據庫的發展狀況如何數據庫有什么新發展
![<b class='flag-5'>數據庫</b>學習教程之<b class='flag-5'>數據庫</b>的發展狀況如何<b class='flag-5'>數據庫</b><b class='flag-5'>有</b>什么新發展](https://file.elecfans.com/web1/M00/69/2C/pIYBAFvRgmuAL-4IAADZUgBfnIQ744.png)
數據庫有哪些常見的應用結構數據庫應用結構的使用資料概述
![<b class='flag-5'>數據庫</b><b class='flag-5'>有</b>哪些常見的應用結構<b class='flag-5'>數據庫</b>應用結構的使用資料概述](https://file.elecfans.com/web1/M00/6A/1D/pIYBAFvZb6aAVGjnAAA7JFDUjeA853.png)
嵌入式Linux 異步IO機制
Linux中如何使用信號驅動式I/O?
![<b class='flag-5'>Linux</b>中如何使用信號驅動式<b class='flag-5'>I</b>/<b class='flag-5'>O</b>?](https://file.elecfans.com/web1/M00/E5/1E/pIYBAGBLFQ-AE-9YAAFrw9ppYpk269.png)
輕量級數據庫有哪些
數據庫數據恢復—SQL Server數據庫出現823錯誤的數據恢復案例
![<b class='flag-5'>數據庫</b><b class='flag-5'>數據</b>恢復—SQL Server<b class='flag-5'>數據庫</b>出現823錯誤的<b class='flag-5'>數據</b>恢復案例](https://file1.elecfans.com/web2/M00/07/F4/wKgaombs78mANJ1GAAPeSoXHVPE244.png)
數據庫數據恢復—通過拼接數據庫碎片恢復SQLserver數據庫
![<b class='flag-5'>數據庫</b><b class='flag-5'>數據</b>恢復—通過拼接<b class='flag-5'>數據庫</b>碎片恢復SQLserver<b class='flag-5'>數據庫</b>](https://file1.elecfans.com/web1/M00/F4/07/wKgaoWcjE32AbQdWAAJD_hojvJc119.png)
評論