IO的常識和相關優化

轉載請附本文鏈接:https://blog.csdn.net/maxlovezyy/article/details/104038335

常識(TODO:加SSD)

  • HDD的是機械盤,當跨磁道操作的時候需要機械式地尋道,平均延時很大,一般認爲在10ms左右。而對於旋轉延時,一般不需要太在意,因爲轉速都很大,相比尋道延時帶來的延時比較小。
  • Disk以sector爲IO的基本單元。這意味着即使寫某個sector的一個字節,也是寫一個sector,sector大小一般是512B。而對於文件系統來說,目前ext4默認是4K爲一個IO單元。
  • Disk有一個默認的最大請求大小(/sys/block//queue/max_sectors_kb),理論上單次IO大小越接近該值,吞吐越大。最直接的理解就是host到device之間的通信開銷降低了,也包括磁頭調度的優化(窗口越大可優化的空間越大),特別是對於NFS、雲盤之類的場景。
  • ext4默認的掛載方式對非direct IO數據block的分配是delay的,也就是fsync之前是不會分配block的,目的是儘可能加大待處理blocks窗口大小以優化數據分佈。但是帶來的問題就是如果積攢的比較多,在分配block時阻塞其他請求的時間就會更長。掛載時可以通過nodelalloc去掉該功能。
  • 調度器。linux IO系統有常用的3種調度器,cfq、deadline和noop。noop適合SSD,cfq適合多應用公平調度場景,deadline適合數據庫和文件系統(原理一樣,可優化的窗口變大了)。

常用優化

  • 最主要的優化就是圍繞減少HDD尋道帶來的開銷進行的。儘量順序寫,降低隨機IO;儘量buffer一波IO,通過batch的方式處理,包括fsync。由於fsync會sync metadata,而metadata又一般在disk上與data分離,所以基本上必定會增加一次尋道的開銷,這麼重的開銷註定吞吐要下來。可以考慮使用預分配文件的方式利用fdatasync(這一塊是有坑等,需要先寫一遍文件,fallocate沒有用)來優化IO。
  • 重新掛載盤,加上nodelalloc參數。目前在離線系統裏看中吞吐而非穩定性的情況下可以不考慮。比如偶爾有一個10s左右的抖動是可接受的。
  • 按4K對齊寫。這方面可以參考之前收藏的小日本的博文,寫得不錯。
  • 爲數據庫等場景設置deadline IO調度器。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章