微網(wǎng)站 微信app關(guān)鍵詞優(yōu)化
(翻譯 《ZFS On-Disk Specification》, 由于是2006年給出的文檔,與當(dāng)前ZFS系統(tǒng)肯定有很多的不同,但是也是一份相當(dāng)有幫助的ZFS學(xué)習(xí)文檔)
?
1.1 虛擬設(shè)備
?
ZFS存儲(chǔ)池是由一個(gè)虛擬設(shè)備集合構(gòu)成的。這里面一共有兩種虛擬設(shè)備:物理虛擬設(shè)備(physical virtual devices,也稱(chēng)為葉虛擬設(shè)備,leaf vdevs),以及邏輯虛擬設(shè)備(logical virtual devices,也稱(chēng)為內(nèi)部虛擬設(shè)備,interior vdevs)。物理設(shè)備是一個(gè)可寫(xiě)的塊設(shè)備(比如一個(gè)磁盤(pán));邏輯設(shè)備在概念上的一組物理設(shè)備。
?
Vdev是通過(guò)一個(gè)以物理設(shè)備為葉子節(jié)點(diǎn)的樹(shù)來(lái)管理的。每一個(gè)pool都有一個(gè)被稱(chēng)為“root vdev”的設(shè)備作為這棵樹(shù)的根。root節(jié)點(diǎn)的所有直接子節(jié)點(diǎn)(無(wú)論是邏輯的還是物理的)都被稱(chēng)為top-level vdevs。下圖顯示了一個(gè)由兩個(gè)Mirror構(gòu)成的pool的虛擬設(shè)備樹(shù)。第一個(gè)Mirror(標(biāo)簽為M1)有兩個(gè)磁盤(pán),分別通過(guò)“vdev A”和“vdev B”來(lái)表示;同樣的,第二個(gè)Mirror(標(biāo)簽為M2)也有兩個(gè)磁盤(pán),分別通過(guò)“vdev C”和“vdev D”來(lái)表示。虛擬設(shè)備A,B,C,D都是物理虛擬設(shè)備。“M1”和“M2”都是邏輯虛擬設(shè)備,由于M1和M2都是root的直接子節(jié)點(diǎn),所以都是“top-level vdevs”。
1.2 虛擬設(shè)備標(biāo)簽(Vdev Label)
?
Pool中的每一個(gè)物理虛擬設(shè)備都包含一個(gè)256K的結(jié)構(gòu)體——vdev_label。這個(gè)Label描述了這個(gè)設(shè)備以及同一top-level vdev下的其他所有虛擬設(shè)備的信息。例如:對(duì)于虛擬設(shè)備C,它的vdev label中包含虛擬設(shè)備C,D以及M2的信息。vdev label的詳細(xì)信息在下一節(jié)中詳細(xì)描述。
?
使用vdev label有兩個(gè)目的:它提供訪問(wèn)pool中信息的入口;另外它還被用于驗(yàn)證pool的完整新和可用性。為了保證vdev label總是合法可用的,我們使用冗余和特殊的更新方式。冗余:pool中的每個(gè)物理虛擬設(shè)備都有4個(gè)相同的Label,同一個(gè)設(shè)備上的4份是完全相同的,不同設(shè)備則是不同的。更新:Label的更新過(guò)程中,使用兩階段的事務(wù)來(lái)更新,這樣確保虛擬設(shè)備上至少有一個(gè)合法的Label。下面詳細(xì)介紹一下Label的冗余和更新技術(shù)。
?
1.2.1 Label<span "="">冗余
?
pool中的每個(gè)物理虛擬設(shè)備都有4份相同的Label,在更新過(guò)程中,這4份Label每一個(gè)都可以用來(lái)訪問(wèn)、驗(yàn)證pool中的數(shù)據(jù)。當(dāng)一個(gè)設(shè)備被添加到pool中時(shí),ZFS在設(shè)備的最前面放兩個(gè)Label,最后面也放兩個(gè)Label。下圖顯示四個(gè)Label的分布,N表示設(shè)備的總大小,L0、L1為前兩個(gè)Label,L2、L3為后兩個(gè)Label。
<span "="">考慮到一般情況下設(shè)備的損壞都是一個(gè)連續(xù)的段,所以要將Label放在兩個(gè)不同的地方。
?
1.2.2 <span "="">兩階段的事務(wù)性更新
?
Label<span "="">的位置是在設(shè)備加入pool時(shí)就設(shè)定好了,因此Label的更新并不能像ZFS對(duì)待其他數(shù)據(jù)那樣采用Copy-On-Write技術(shù),也就是說(shuō),對(duì)Label的更新是直接覆蓋原有的數(shù)據(jù)。但是在寫(xiě)任何數(shù)據(jù)的過(guò)程中都有可能發(fā)生錯(cuò)誤,為了保證ZFS任何時(shí)候總是有一個(gè)合法的Label,Label的更新過(guò)程被分為兩個(gè)階段。第一階段更新偶數(shù)的Label(L0、L2),如果在這一階段中任何時(shí)刻發(fā)生了錯(cuò)誤,奇數(shù)Label(L1、L3)仍然是合法的。在L0、L2更新結(jié)束之后,第二階段則是更新L1、L3。
?
1.3 vdev技術(shù)細(xì)節(jié)
?
vdev label的信息被分成了4部分:8K的空閑空間(Blank Space),8K的boot header信息,112K的name-value鍵值對(duì)以及128長(zhǎng)度的1K大小的uberblock結(jié)構(gòu)數(shù)組。下圖顯示了L0的擴(kuò)展視圖。
1.3.1 <span "="">空閑空間
?
ZFS支持使用VTOC(Volume Table of Content)和EFI兩種方式來(lái)描述磁盤(pán)布局。EFI標(biāo)簽并不是Slice的一部分(它有自己的保留空間),VTOC標(biāo)簽必須被寫(xiě)在Slice0的前8K空間內(nèi),所以為了支持VTOC標(biāo)簽,vdev_label的前8K空間被保留下來(lái)防止重寫(xiě)了VTOC標(biāo)簽。
?
1.3.2 Boot Block Header
?
保留,以后使用。
?
1.3.3 Name-Value Pair List
?
后面的112KB存儲(chǔ)描述這個(gè)設(shè)備以及其關(guān)聯(lián)設(shè)備的鍵值對(duì)。關(guān)聯(lián)設(shè)備即:同一個(gè)top level vdev下的設(shè)備。比如下圖中的灰色圓內(nèi)部的A,B,M1三個(gè)設(shè)備。
所有的鍵值對(duì)都使用XDR encoded nvlists存儲(chǔ)。關(guān)于更多的XDR encoding或是nvlists請(qǐng)參見(jiàn) libnvpair(3LIB)和nvlist_free(3NVPAIR)man手冊(cè)。以下的鍵值對(duì)都被包含在這112K的部分內(nèi)。
vdev_tree遞歸地描述與當(dāng)前vdev相關(guān)的vdev的信息。
每個(gè)vdev_tree都包含以下信息:
?
1.3.4 uberblock
?
nvlist之后就是uberblock的數(shù)組。uberblock是訪問(wèn)pool中數(shù)據(jù)的入口。任意時(shí)刻,只有一個(gè)uberblock處于激活狀態(tài),所有uberblock中事務(wù)組編號(hào)最高且通過(guò)SHA-256 checksum驗(yàn)證合法的uberblock為激活的uberblock,它類(lèi)似于UFS文件系統(tǒng)中的超級(jí)塊。
?
為了能夠持續(xù)訪問(wèn)激活的uberblock,激活的uberblock永遠(yuǎn)不會(huì)被覆蓋。所有對(duì)uberblock的修改都是通過(guò)寫(xiě)入uberblock數(shù)組中的另外一個(gè)元素來(lái)完成的。在寫(xiě)入新的uberblock時(shí),事務(wù)組編號(hào)以及時(shí)間戳都是在同一個(gè)原子性的操作中完成。Uberblock通過(guò)循環(huán)的方式寫(xiě)入。
?
下圖顯示兩個(gè)uberblock。
uberblock技術(shù)細(xì)節(jié)
?
uberblock按照機(jī)器的字節(jié)模式存儲(chǔ)。
?
ub_magic
?
用于表示該設(shè)備包含ZFS數(shù)據(jù)。ub_magic的值為0x00bab10c(oo-ba-bloc)
?
ub_version
?
版本號(hào),與前文中鍵值對(duì)的版本號(hào)意義相同。
?
ub_txg
?
ZFS中所有的寫(xiě)操作都是通過(guò)事務(wù)組來(lái)完成的。每個(gè)事務(wù)組都有一個(gè)對(duì)應(yīng)的事務(wù)組編號(hào)。ub_txg用來(lái)表示寫(xiě)入這個(gè)uberblock的事務(wù)組編號(hào)。ub_txg必須大于等于前面鍵值對(duì)中的txg編號(hào)。
?
ub_guid_sum
?
用來(lái)檢驗(yàn)pool中所有設(shè)備的可用性。當(dāng)pool被打開(kāi)后,ZFS遍歷pool中所有的葉虛擬設(shè)備計(jì)算這些GUID的和,然后與ub_guid_sum進(jìn)行比較,來(lái)驗(yàn)證pool中磁盤(pán)的可用性。
?
ub_timestamp
?
當(dāng)前uberblock寫(xiě)入的時(shí)間戳(1970年1月1日至今的秒數(shù))
?
ub_rootbp
?
這是一個(gè)blkptr結(jié)構(gòu)體,包含了MOS的位置。MOS和blkptr將在后文中詳細(xì)描述。
?
1.4 Boot Block
?
L0和L1之后有一個(gè)3.5M的保留空間。