31 | 套路篇:磁盘 I/O 性能优化的几个思路
生活随笔
收集整理的這篇文章主要介紹了
31 | 套路篇:磁盘 I/O 性能优化的几个思路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一節,我們一起回顧了常見的文件系統和磁盤 I/O 性能指標,梳理了核心的 I/O 性能觀測工具,最后還總結了快速分析 I/O 性能問題的思路。雖然 I/O 的性能指標很多,相應的性能分析工具也有好幾個,但理解了各種指標的含義后,你就會發現它們其實都有一定的關聯。順著這些關系往下理解,你就會發現,掌握這些常用的瓶頸分析思路,其實并不難。找出了 I/O 的性能瓶頸后,下一步要做的就是優化了,也就是如何以最快的速度完成 I/O 操作,或者換個思路,減少甚至避免磁盤的 I/O 操作。今天,我就來說說,優化 I/O 性能問題的思路和注意事項。
I/O 基準測試
按照我的習慣,優化之前,我會先問自己, I/O 性能優化的目標是什么?換句話說,我們觀察的這些 I/O 性能指標(比如 IOPS、吞吐量、延遲等),要達到多少才合適呢?事實上,I/O 性能指標的具體標準,每個人估計會有不同的答案,因為我們每個人的應用場景、使用的文件系統和物理磁盤等,都有可能不一樣。為了更客觀合理地評估優化效果,我們首先應該對磁盤和文件系統進行基準測試,得到文件系統或者磁盤 I/O 的極限性能。fio(Flexible I/O Tester)正是最常用的文件系統和磁盤 I/O 性能基準測試工具。它提供了大量的可定制化選項,可以用來測試,裸盤或者文件系統在各種場景下的 I/O 性能,包括了不同塊大小、不同 I/O 引擎以及是否使用緩存等場景。fio 的安裝比較簡單,你可以執行下面的命令來安裝它:# Ubuntu apt-get install -y fio# CentOS yum install -y fio安裝完成后,就可以執行 man fio 查詢它的使用方法。fio 的選項非常多, 我會通過幾個常見場景的測試方法,介紹一些最常用的選項。這些常見場景包括隨機讀、隨機寫、順序讀以及順序寫等,你可以執行下面這些命令來測試:# 隨機讀 fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb# 隨機寫 fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb# 順序讀 fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb# 順序寫 fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb在這其中,有幾個參數需要你重點關注一下。- direct,表示是否跳過系統緩存。上面示例中,我設置的 1 ,就表示跳過系統緩存。
- iodepth,表示使用異步 I/O(asynchronous I/O,簡稱 AIO)時,同時發出的 I/O 請求上限。在上面的示例中,我設置的是 64。
- rw,表示 I/O 模式。我的示例中, read/write 分別表示順序讀 / 寫,而 randread/randwrite 則分別表示隨機讀 / 寫。
- ioengine,表示 I/O 引擎,它支持同步(sync)、異步(libaio)、內存映射(mmap)、網絡(net)等各種 I/O 引擎。上面示例中,我設置的 libaio 表示使用異步 I/O。
- bs,表示 I/O 的大小。示例中,我設置成了 4K(這也是默認值)。
- filename,表示文件路徑,當然,它可以是磁盤路徑(測試磁盤性能),也可以是文件路徑(測試文件系統性能)。示例中,我把它設置成了磁盤 /dev/sdb。不過注意,用磁盤路徑測試寫,會破壞這個磁盤中的文件系統,所以在使用前,你一定要事先做好數據備份。
- slat ,是指從 I/O 提交到實際執行 I/O 的時長(Submission latency);
- clat ,是指從 I/O 提交到 I/O 完成的時長(Completion latency);
- 而 lat ,指的是從 fio 創建 I/O 到 I/O 完成的總時長。
I/O 性能優化
得到 I/O 基準測試報告后,再用上我們上一節總結的性能分析套路,找出 I/O 的性能瓶頸并優化,就是水到渠成的事情了。當然, 想要優化 I/O 性能,肯定離不開 Linux 系統的 I/O 棧圖的思路輔助。你可以結合下面的 I/O 棧圖再回顧一下。下面,我就帶你從應用程序、文件系統以及磁盤角度,分別看看 I/O 性能優化的基本思路。應用程序優化
首先,我們來看一下,從應用程序的角度有哪些優化 I/O 的思路。應用程序處于整個 I/O 棧的最上端,它可以通過系統調用,來調整 I/O 模式(如順序還是隨機、同步還是異步), 同時,它也是 I/O 數據的最終來源。在我看來,可以有這么幾種方式來優化應用程序的 I/O 性能。- 第一,可以用追加寫代替隨機寫,減少尋址開銷,加快 I/O 寫的速度。
- 第二,可以借助緩存 I/O ,充分利用系統緩存,降低實際 I/O 的次數。
- 第三,可以在應用程序內部構建自己的緩存,或者用 Redis 這類外部緩存系統。這樣,一方面,能在應用程序內部,控制緩存的數據和生命周期;另一方面,也能降低其他應用程序使用緩存對自身的影響。
- 第四,在需要頻繁讀寫同一塊磁盤空間時,可以用 mmap 代替 read/write,減少內存的拷貝次數。
- 第五,在需要同步寫的場景中,盡量將寫請求合并,而不是讓每個請求都同步寫入磁盤,即可以用 fsync() 取代 O_SYNC。
- 第六,在多個應用程序共享相同磁盤時,為了保證 I/O 不被某個應用完全占用,推薦你使用 cgroups 的 I/O 子系統,來限制進程 / 進程組的 IOPS 以及吞吐量。
文件系統優化
應用程序訪問普通文件時,實際是由文件系統間接負責,文件在磁盤中的讀寫。所以,跟文件系統中相關的也有很多優化 I/O 性能的方式。- 第一,你可以根據實際負載場景的不同,選擇最適合的文件系統。比如 Ubuntu 默認使用 ext4 文件系統,而 CentOS 7 默認使用 xfs 文件系統。
- 第二,在選好文件系統后,還可以進一步優化文件系統的配置選項,包括文件系統的特性(如 ext_attr、dir_index)、日志模式(如 journal、ordered、writeback)、掛載選項(如 noatime)等等。
- 第三,可以優化文件系統的緩存。
磁盤優化
數據的持久化存儲,最終還是要落到具體的物理磁盤中,同時,磁盤也是整個 I/O 棧的最底層。從磁盤角度出發,自然也有很多有效的性能優化方法。- 第一,最簡單有效的優化方法,就是換用性能更好的磁盤,比如用 SSD 替代 HDD。
- 第二,我們可以使用 RAID ,把多塊磁盤組合成一個邏輯磁盤,構成冗余獨立磁盤陣列。這樣做既可以提高數據的可靠性,又可以提升數據的訪問性能。
- 第三,針對磁盤和應用程序 I/O 模式的特征,我們可以選擇最適合的 I/O 調度算法。比方說,SSD 和虛擬機中的磁盤,通常用的是 noop 調度算法。而數據庫應用,我更推薦使用 deadline 算法。
- 第四,我們可以對應用程序的數據,進行磁盤級別的隔離。比如,我們可以為日志、數據庫等 I/O 壓力比較重的應用,配置單獨的磁盤。
- 第五,在順序讀比較多的場景中,我們可以增大磁盤的預讀數據,比如,你可以通過下面兩種方法,調整 /dev/sdb 的預讀大小。
- 調整內核選項 /sys/block/sdb/queue/read_ahead_kb,默認大小是 128 KB,單位為 KB。
- 使用 blockdev 工具設置,比如 blockdev --setra 8192 /dev/sdb,注意這里的單位是 512B(0.5KB),所以它的數值總是 read_ahead_kb 的兩倍。
- 第六,我們可以優化內核塊設備 I/O 的選項。比如,可以調整磁盤隊列的長度 /sys/block/sdb/queue/nr_requests,適當增大隊列長度,可以提升磁盤的吞吐量(當然也會導致 I/O 延遲增大)。
小結
今天,我們一起梳理了常見的文件系統和磁盤 I/O 的性能優化思路和方法。發現 I/O 性能問題后,不要急于動手優化,而要先找出最重要的、可以最大程度提升性能的問題,然后再從 I/O 棧的不同層入手,考慮具體的優化方法。記住,磁盤和文件系統的 I/O ,通常是整個系統中最慢的一個模塊。所以,在優化 I/O 問題時,除了可以優化 I/O 的執行流程,還可以借助更快的內存、網絡、CPU 等,減少 I/O 調用。比如,你可以充分利用系統提供的 Buffer、Cache ,或是應用程序內部緩存, 再或者 Redis 這類的外部緩存系統。思考在整個板塊的學習中,我只列舉了最常見的幾個 I/O 性能優化思路。除此之外,還有很多從應用程序、系統再到磁盤硬件的優化方法。我想請你一起來聊聊,你還知道哪些其他優化方法嗎?總結
以上是生活随笔為你收集整理的31 | 套路篇:磁盘 I/O 性能优化的几个思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 30 | 套路篇:如何迅速分析出系统I/
- 下一篇: 32 | 答疑(四):阻塞、非阻塞 I/