ZFS文件系統的特點和調優

網上收集:http://www.ixpub.net/thread-766068-1-1.html

 

ZFS文件系統在設計上與傳統的文件系統有很大的不同。我們需要對ZFS的幾個基本概念有
所瞭解:
Record Size
Record Size 也就是通常所說的文件系統的block size。ZFS採用的是動態的Record Size,也就
是說ZFS會根據文件大小選擇*適合*的512字節的整數倍作爲存儲的塊大小,最大的Record
Size爲128KB。通常沒有必要手工設置Record Size。如果手工把Record Size調小,將不會得
到空間的節省,並且常常會影響性能。ZFS的Block是計算checksum的單位,一個文件用到
的block越多,計算checksum以及維護metadata的開銷就會越大。
目前ZFS的版本下,只有一種情況需要手工調小Record Size:大文件上的小數據量的更新。
常見的情況是數據庫的數據文件在ZFS上,並且是做OLTP爲主的應用。原因是大文件的
blocksize是128KB,如果只更新其中一小部分數據,由於ZFS是copy-on-write的方式來更新
數據,這種情況下仍然要讀寫128KB的數據,造成了不必要的開銷。
另外,修改了Record Size後,對之前創建的文件不起作用。
ARC (Adaptive Replacement Cache)
這實際上是ZFS的文件系統的cache。它是一個可以自動伸縮的cache。目前一個操作系統實
例裏只有一個ARC,不管這個操作系統上有多少個ZFS Pool。而且metadata和實際的數據都
共用這個ARC。
如果沒有其它應用或操作系統本身爭用內存,ZFS會儘可能多地使用物理內存作爲cache。如
果事先知道應用程序或操作系統需要使用多少內存,可以考慮限制ARC的大小。在/etc/system
中設置,例子:set zfs:zfs_arc_max=0x200000000 (設置ARC最大爲8GB)
還可以使用如下工具來監測ARC的使用情況。

bash-3.00# ./zfs_arcstat.pl
Time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
14:41:03 10M 2M 21 2M 21 0 0 97K 77 2G 2G
14:41:04 890 228 25 228 25 0 0 8 100 2G 2G
14:41:05 1K 273 25 273 25 0 0 7 100 2G 2G
14:41:06 880 221 25 221 25 0 0 5 100 2G 2G
14:41:07 1K 272 25 272 25 0 0 10 52 2G 2G
14:41:08 1K 244 24 244 24 0 0 4 100 2G 2G
14:41:09 1K 294 25 294 25 0 0 10 100 2G 2G
14:41:10 1K 258 25 258 25 0 0 6 66 2G 2G

各列的含義,在這個Perl腳本里有描述。該工具的下載地址是:
http://www.solarisinternals.com/wiki/index.php/Arcstat
TXG (Transaction Groups)
應用的文件寫操作一般分爲兩種,同步寫和普通寫操作。同步寫是指寫操作必須物理地寫到
存儲介質上才能返回給應用,通常這種情況發生在open文件時指定了O_DSYNC或O_SYNC
屬性,以及調用fsync()等;普通寫操作是指寫操作寫到文件系統cache裏即可返回給應用,通
常以普通方式打開文件後的write(),fwrite()操作都是這種操作。TXG (Transaction Groups)則是
負責管理如何將文件系統cache(ARC)裏的數據同步到磁盤上的機制。
對於寫進文件系統cache裏的每一個數據都會被編入一個TXG,通常情況下每隔5秒鐘或文件
系統cache裏有太多髒數據(待寫入磁盤的數據達到ARC的一半),當前TXG裏的所有數據
會被同步到磁盤,同時啓動下一個TXG。每一個ZFS Pool同時最多會有3個TXG,分別處於
3種狀態:open, quiescing, syncing。當TXG不能在5秒內把數據同步到磁盤上時將會影響
open TXG,從而引起應用寫操作的阻塞。這個現象叫做寫抑制(throttling)。
當前的Solaris 版本(Solaris 10 8/07)對寫抑制的控制不是非常好,當進行密集的寫操作並且
ARC較大、磁盤系統較慢時容易使TXG同步數據的時間非常長,發生throttling從而使應用的
後續寫操作的響應時間非常長。在新的opensolaris發行包裏,這個問題已經有了很大的改進,
ZFS會監測ARC接收數據的速度和ARC數據同步到磁盤上的速度,並自動調整ARC接收數
據的速度。另外ARC髒數據的大小限制改爲1/8物理內存。通過這種控制可以使應用的寫操
作響應時間更爲均勻穩定。
ZIL (ZFS Intent Log)
對於同步寫操作,ZFS爲系統中每一個ZFS文件系統維護一個ZIL(ZFS Intent log)。同步寫操
作的數據會先寫入ZIL,並且會把磁盤的write cache的數據同步到磁盤上,然後應用的寫操作
返回。當文件提交命令發生時,ZFS會把ZIL裏該文件的數據同步到磁盤上。
缺省情況下,ZIL是在ZFS存儲池中動態分配的。某些同步寫操作(比如數據庫的聯機重做日
志或NFS COMMIT)如果響應時間慢將會極大影響性能。爲了不使ZIL受其它I/O操作的影
響,可以考慮採用一個專門的快速設備如NVRAM,SSD(Solid State Disk)等做ZIL,以下命令
爲ZFS存儲池添加專用的ZIL:
zpool add <pool> log <log devices>
另外,由於每次同步寫操作會使ZFS把磁盤 write cache的數據同步到磁盤上,對於SAN的存
儲,頻繁地flush cache會嚴重影響性能並且是不必要的。這個問題在OpenSolaris裏已經得到
解決,解決辦法是讓設備驅動程序向存儲系統發出適當的命令選項,從而使存儲系統可以忽
略從non-volatile cache同步到磁盤的請求。前提是存儲系統可以識別驅動程序發出的命令選項。
I/O scheduler and priorities
缺省情況下,ZFS會限制每一個它能看到的存儲池裏的設備的I/O隊列長度爲35,並且通常讀
操作的優先級高於寫操作。這種做法的目的是保證較好的I/O service time。
根據實際的應用需求和存儲設備的不同,可能需要調整I/O隊列的大小。比如爲了得到更好地
響應時間,在/etc/system裏設置:set zfs:zfs_vdev_max_pending = 10
Prefetch (file level and device level)
和其它文件系統一樣,ZFS也有預讀的功能。ZFS文件系統的預讀分爲file-level和devicelevel

file-level的預讀是指ZFS可以檢測到文件讀取的模式,預先讀入文件的後續部分從而減少I/O
操作以提高性能。對於大併發量的針對不同文件的讀操作,file-level的預讀通常不會帶來好處,
可以把預讀關掉:在/etc/system裏設置:set zfs:zfs_prefetch_disable = 1 。
Device-level的預讀是指在讀取數據塊時,會讀取設備相鄰的數據,假定相鄰數據隨後會被用
到。Device-level的預讀有時會讀入不需要的數據反而會影響性能,在新的opensolaris發行包
裏,Device-level的預讀只預讀metadata。
RAIDZ and RAIDZ2
ZFS提供了類似傳統RAID5和RAID6的功能,分別叫做RAIDZ和RAIDZ2。但RAIDZ的實
現與傳統RAID5有很大不同:RAIDZ的所有寫操作都是Full-Stripe write,結合ZFS的copyon-
write和checksum的機制,可以保證數據的一致性,無需像傳統的RAID5那樣需要昂貴的
NVRAM來保證條帶數據的一致性。
RAIDZ的stripe size是完全動態的。每一個文件系統塊(record)在存儲時會平均分配到RAIDZ
group裏的所有磁盤上,並以512字節爲單位。例如,假設一個4KB的文件,如果存儲在4+1
的RAIDZ group,則4KB的數據會分散到4個磁盤上,每個磁盤上存儲1KB。因此一個
RAIDZ group裏的設備不應過多,否則會影響讀操作的性能。一般建議爲3~9個。RAIDZ比
較適合大文件的順序讀寫。
由於RAIDZ在設計上的特殊性,在數據恢復時需要通過metadata來恢復,要遍歷整個pool。
當某塊磁盤出現故障時,RAIDZ重建的速度與metadata的數量有關。當有大量metadata數據
時,比如大量snapshots或pool裏的文件數量龐大,數據重建的速度會較慢。在這種情況下,
可以考慮創建多個pool。當然,對一個很空的文件系統,RAIDZ的重建時間會很短。

 

發佈了31 篇原創文章 · 獲贊 7 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章