由於各種的I/O負載情形各異,Linux系統中檔案系統的預設配置一般來說都比較中庸,強調普遍適用性。然而在特定應用下,這種配置往往在I/O效能方面不能達到最優。因此,如果應用對I/O效能要求較高,除了採用效能更高的硬體(如磁碟、HBA卡、CPU、MEM等)外,我們還可以通過對檔案系統進行效能調優,來獲得更高的I/O效能提升。總的來說,主要可以從三個方面來做工作:
1、Disk相關參數調優
2、檔案系統本身參數調優
3、檔案系統掛載(mount)參數調優
當然,負載情況不同,需要結合理論分析與充分的測試和實驗來得到合理的參數。下面以SAS(Serial attached SCSI)磁碟上的EXT3檔案系統為例,給出Linux檔案系統效能最佳化的一般方法。請根據自身情況作適合調整,不要生搬硬套。
1、Disk相關參數
1.1 Cache mode:啟用WCE=1(Write Cache Enable), RCD=0(Read Cache Disable)模式
sdparm -s WCE=1, RCD=0 -S /dev/sdb
1.2 Linux I/O scheduler演算法
經過實驗,在重負載情形下,deadline調度方式對squidI/O負載具有更好的效能表現。其他三種為noop(fifo), as, cfq,noop多用於SAN/RAID儲存系統,as多用於大檔案順序讀寫,
cfq適於案頭應用。
echo deadline > /sys/block/sdb/queue/scheduler
1.3 deadline調度參數
對於redhat linux建議 read_expire = 1/2 write_expire,對於大量頻繁的小檔案I/O負載,應當這兩者取較小值。更合適的值,需要通過實驗測試得到。
echo 500 > /sys/block/sdb/queue/iosched/read_expire
echo 1000 > /sys/block/sdb/queue/iosched/write_expire
1.4 readahead 預讀扇區數
預讀是提高磁碟效能的有效手段,目前對順序讀比較有效,主要利用資料的局部性特點。比如在我的系統上,通過實驗設定通讀256塊扇區效能較優。
blockdev --setra 256 /dev/sdb
2、EXT3檔案系統參數
2.1 block size = 4096 (4KB)
mkfs.ext3 -b指定,大的資料區塊會浪費一定空間,但會提升I/O效能。EXT3檔案系統塊大小可以為1KB、2KB、4KB。
2.2 inode size
這是一個邏輯概念,即一個inode所對應的檔案相應佔用多大物理空間。mkfs.ext3 -i指定,可用檔案系統檔案大小平均值來設定,可減少磁碟定址和中繼資料操作時間。
2.3 reserved block
mkfs.ext3 -m指定,預設為5%,可調小該值以增大部分可用儲存空間。
2.4 disable journal
對資料安全要求不高的應用(如web cache),可以關閉日誌功能,以提高I/O效能。
tune2fs -O^has_journal /dev/sdb
3、mount參數
3.1 noatime, nodirtime
訪問檔案目錄,不修改訪問檔案元資訊,對於頻繁的小檔案負載,可以有效提高效能。
3.2 async
非同步I/O方式,提高寫效能。
3.3 data=writeback (if journal)
記錄模式下,啟用寫回機制,可提高寫效能。資料寫入順序不再保護,可能會造成檔案系統資料不一致性,重要資料應用慎用。
3.4 barrier=0 (if journal)
barrier=1,可以保證檔案系統在日誌資料寫入磁碟之後才寫commit記錄,但影響效能。重要資料應用慎用,有可能造成資料損毀。
4、小結
以/dev/sdb為例,最佳化操作方法如下,參數請自行調整。
sdparm -s WCE=1, RCD=0 -S /dev/sdb
echo deadline > /sys/block/sdb/queue/scheduler
echo 500 > /sys/block/sdb/queue/iosched/read_expire
echo 1000 > /sys/block/sdb/queue/iosched/write_expire
blockdev --setra 256 /dev/sdb
mkfs.ext3 -b 4096 -i 16384 -m 2 /dev/sdb1
tune2fs -O^has_journal /dev/sdb1
mount /dev/sdb1 /cache1 -o defaults,noatime,nodirtime,async,data=writeback,barrier=0 (if with journal)
mount /dev/sdb1 /cache1 -o defaults,noatime,nodirtime,async (if without journal)