mysql 使用异步io_InnoDB引擎之-异步IO(Async IO)
InnoDB引擎有幾個(gè)重點(diǎn)特性,為其帶來了更好的性能和可靠性:
插入緩沖(Insert Buffer)
兩次寫(Double Write)
自適應(yīng)哈希索引(Adaptive Hash Index)
異步IO(Async IO)
刷新鄰接頁(Flush Neighbor Page)
關(guān)于AIO與SIO
為了提高磁盤操作性能,當(dāng)前的數(shù)據(jù)庫系統(tǒng)都采用異步IO的方式來處理磁盤操作。
同步IO:我們常用的read/write函數(shù)(Linux上)就是這類IO,特點(diǎn)是,在函數(shù)執(zhí)行的時(shí)候,調(diào)用者會(huì)等待函數(shù)執(zhí)行完成,而且沒有消息通知機(jī)制,因?yàn)楹瘮?shù)返回了,就表示操作完成了,后續(xù)直接檢查返回值就可知道操作是否成功。這類IO操作,編程比較簡(jiǎn)單,在同一個(gè)線程中就能完成所有操作,但是需要調(diào)用者等待,在數(shù)據(jù)庫系統(tǒng)中,比較適合急需某些數(shù)據(jù)的時(shí)候調(diào)用,例如WAL中日志必須在返回客戶端前落盤,則進(jìn)行一次同步IO操作。
異步IO:在數(shù)據(jù)庫中,后臺(tái)刷數(shù)據(jù)塊的IO線程,基本都使用了異步IO。數(shù)據(jù)庫前臺(tái)線程只需要把刷塊請(qǐng)求提交到異步IO的隊(duì)列中即可返回做其他事情,而后臺(tái)線程IO線程,則定期檢查這些提交的請(qǐng)求是否已經(jīng)完成,如果完成再做一些后續(xù)處理工作。同時(shí)異步IO由于常常是一批一批的請(qǐng)求提交,如果不同請(qǐng)求訪問同一個(gè)文件且偏移量連續(xù),則可以合并成一個(gè)IO請(qǐng)求。例如,第一個(gè)請(qǐng)求讀取文件1,偏移量100開始的200字節(jié)數(shù)據(jù),第二個(gè)請(qǐng)求讀取文件1,偏移量300開始的100字節(jié)數(shù)據(jù),則這兩個(gè)請(qǐng)求可以合并為讀取文件1,偏移量100開始的300字節(jié)數(shù)據(jù)。數(shù)據(jù)預(yù)讀中的邏輯預(yù)讀也常常使用異步IO技術(shù)。
Innodb 使用異步IO的場(chǎng)景
總的來說innodb 只會(huì)對(duì)數(shù)據(jù)文件采用異步IO,為了保存日志是真正被寫入到磁盤,innodb不會(huì)對(duì)日志文件啟用異步IO;innodb只會(huì)對(duì)數(shù)據(jù)文件的read-ahead ,write 這兩個(gè)操作啟用異步IO
異步IO在mysql中解決了什么問題
在沒有IO這個(gè)功能之前,innodb對(duì)數(shù)據(jù)的讀寫請(qǐng)求先放入任務(wù)隊(duì)列,后臺(tái)read-thread ,write-thread從任務(wù)隊(duì)列中拿出任務(wù)并執(zhí)行讀寫操作;后臺(tái)讀寫線程的個(gè)數(shù)可以通過show engine innodb status 語句來查看
show engine innodb status;
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
376 OS file reads, 54 OS file writes, 7 OS fsyncs
41.77 reads/s, 21886 avg bytes/read, 6.00 writes/s, 0.78 fsyncs/s
由上面的內(nèi)容可以看出默認(rèn)情況下innodb會(huì)有4個(gè)read-thread 和4個(gè)write-thread ,問題就出現(xiàn)在這里,如果業(yè)務(wù)繁重,讀寫任務(wù)會(huì)非常的多,而innodb只有八個(gè)讀寫線程,這樣的話隊(duì)列中的其它讀寫請(qǐng)求就沒能得到及時(shí)的響應(yīng)。
引入異步IO之后,讀寫請(qǐng)求不再像之前那樣先放入隊(duì)列,等著后臺(tái)的讀寫線程去執(zhí)行任務(wù);而是查詢線程直接發(fā)起異步請(qǐng)求,這樣一來沖破了讀寫線程個(gè)數(shù)的硬性限制,二來由于異步IO是否阻塞的這也進(jìn)一步提高了性能。
怎么啟用mysql異步IO
首先OS要有異步io,且開啟,然后mysqld要鏈接,要不然OS異步io沒有開啟,數(shù)據(jù)庫的異步io也起不來。(this variable applies to Linux systems only, and cannot be changed while the server is running.)
文件系統(tǒng)層面需要打開這個(gè)功能:
一般都是默認(rèn)開啟的。
ldconfig -v|grep libaio
libaio.so.1.0.0 -> libaio.so.1.0.0
libaio.so.1 -> libaio.so.1.0.1
AIO是數(shù)據(jù)庫層面的一個(gè)特性需要打開:
默認(rèn)是開啟,但是阿里云默認(rèn)是關(guān)閉的,開啟的native aio性能提升,可以提高到75%。
mysql>show variables like 'innodb_use_native_aio';
+-------------------------+-----------------+
| Variable_name | Value |
+-------------------------+-----------------+
| innodb_use_native_aio | OFF |
+-------------------------+-----------------+
異步IO的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
不用等待直接響應(yīng)上一個(gè)用戶的請(qǐng)求;
多次的請(qǐng)求在一起排序,請(qǐng)求的數(shù)據(jù)頁是在一起的,一次讀出來,減少多次讀。(數(shù)據(jù)庫的讀寫請(qǐng)求隊(duì)列放在文件系統(tǒng)中單獨(dú)分配的一塊小內(nèi)存結(jié)構(gòu)里,非文件系統(tǒng)的緩存)
缺點(diǎn)
異步IO對(duì)于我們來說是不可控的,所以說在啟用異步IO的情況下相當(dāng)于是我們把IO的控制權(quán)交出去了。
總結(jié)
以上是生活随笔為你收集整理的mysql 使用异步io_InnoDB引擎之-异步IO(Async IO)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无线网络:家庭 WiFi 的安全隐患及实
- 下一篇: mysql 写入慢_MySQL主从,你遇