總共測試了三種組態,分別是JBOD(3),RAIDZ(4),mirror(2)x2。分別在正常下,硬碟故障下,以及從故障情況下復原後的ZFS寫入讀取行為。
資料改用英文字母代表加上數字代表ZFS將檔案分割的狀況,每一個字母代表相同的檔案,數字代表同一個檔案的第幾個分割,分割的大小由ZFS動態分配,不一定是相等大小。測試JBOD(3),RAIDZ(4)時故障硬碟使用關閉虛擬機器,變更虛擬硬碟的方式模擬。測試mirror(2)x2則使用zpool的offline和online指令模擬硬碟故障。
表格非常多,還沒想到更好得整理方式,請見諒。
[1] | zpool底下有3顆硬碟,類似JBOD的組態,ZFS的寫入讀取行為 | |||||||||||
zpool | ||||||||||||
1 | ||||||||||||
2 | ||||||||||||
3 | ||||||||||||
首先是正常情況下的寫入和讀取行為 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料A | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配硬碟資料 | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||||
online | n/a | 1 | online | n/a | A | A1 | A1 | A1 | ||||
2 | online | n/a | A2 | A2 | A2 | |||||||
3 | online | n/a | A3 | A3 | A3 | |||||||
資料分成三份A1、A2、A3分別寫入3顆硬碟,速度大約是3顆硬碟合併的水準,寫入行為與RAID0相似。但是觀察zpool iostat,檔案並不一定會平均分配成三等份,會動態的調整所以3顆硬碟的寫入量並不一致,但是調整的邏輯不確定。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
online | n/a | 1 | online | A1 | A1 | A | A | A1 | ||||
2 | online | A2 | A2 | A2 | ||||||||
3 | online | A3 | A3 | A3 | ||||||||
從3顆硬碟分別讀取A1、A2、A3,檢查checksum之後再加以合併,速度大約是3顆硬碟合併,讀取行為與RAID0相似。但是因為一開始資料並不是絕對分成三等份,依資料的分配不同,速度是可能會低於RAID0的讀取。 | ||||||||||||
再來是JBOD組態中有一個硬碟故障的情況下。VM中移除1顆硬碟。 | ||||||||||||
zpool status | vdev type | disc | disc status | |||||||||
unavail | n/a | 1 | unavail | |||||||||
2 | online | |||||||||||
3 | online | |||||||||||
開機完zpool出現錯誤訊息,unavail的zpool就不會掛上檔案系統,所以根本看不到檔案,更不用說測試了,結果如預期,行為與RAID0相似。 後續補充測試:這時原本掛載JBOD的檔案系統路徑,還是進的去,只是寫入的資料變成寫入syspool。就算後續把JBOD硬碟全部在VM中移除,開機後zpool status還是看得到故障的JBOD。只是zfs list指令就看不到JBOD的檔案系統。 再把JBOD的硬碟接回去,JBOD中的檔案就完整無缺。 | ||||||||||||
再來是JBOD組態中有2個硬碟故障的情況下。VM中移除2顆硬碟。 | ||||||||||||
zpool status | vdev type | disc | disc status | |||||||||
unavail | n/a | 1 | unavail | |||||||||
2 | unavail | |||||||||||
3 | online | |||||||||||
同樣開機完zpool出現錯誤訊息,unavail的zpool就不會掛上檔案系統,所以根本看不到檔案,更不用說測試了,結果如預期,行為與RAID0相似。 | ||||||||||||
把移除的硬碟接回原來位置。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
online | n/a | 1 | online | A1 | A1 | A | A | A1 | ||||
2 | online | A2 | A2 | A2 | ||||||||
3 | online | A3 | A3 | A3 | ||||||||
把原本的硬碟接回去之後,原本的資料不會有任何影響,因為unavail狀態下,根本不能存取。也不會出現任何Resilver的紀錄。 回復正常後讀取行為和正常情況下相同。 後續補充測試:但是之前寫入syspool的檔案就不見了,不過把相同檔案系統路徑的zpool移除,就可以再相同路徑下,從syspool讀到資料,東西還是在。所以zpool故障嚴重到無法掛載zpool的檔案系統時,請不要亂寫入資料到相同的路徑,雖然不會寫入到異空間去,至少我不知道檔案到哪去了。 | ||||||||||||
使用空白硬碟接回原來拔下來的故障硬碟位置。 | ||||||||||||
因為unavail狀態下,根本不能存取和變更zpool組態。正常下所以想故意這樣做也不行,因為使用zpool replace時加上-f強制指令也沒作用。 但是可以destroy狀態是unavail的zpool,這動作只會把故障的zpool從清單上移除,但是不會動到硬碟內的資料,所以只要記得原本的zpool名稱,原本zpool組成硬碟都還在的情況下,而且沒有動到內部資料的情況下,可以再次用zpool import指令把剛剛destroy的zpool匯入,資料都會還在。 | ||||||||||||
使用空白硬碟接回原來拔下來的故障硬碟位置。 | ||||||||||||
因為unavail狀態下,根本不能存取和變更zpool組態。正常下所以想故意這樣做也不行,因為使用zpool replace時加上-f強制指令也沒作用。 但是可以destroy狀態是unavail的zpool,這動作只會把故障的zpool從清單上移除,但是不會動到硬碟內的資料,所以只要記得原本的zpool名稱,原本zpool組成硬碟都還在的情況下,而且沒有動到內部資料的情況下,可以再次用zpool import指令把剛剛destroy的zpool匯入,資料都會還在。 | ||||||||||||
簡單的說明ZFS在最基本類似JBOD組態下的行為 1. 基本上就是接近RAID0的寫入和讀取行為。 2. 只是ZFS再分割資料給不同硬碟時,會動態的依照硬碟的狀況(雖然我不太能確定是依照硬碟剩餘容量、寫入速度、讀取速度、反應時間、甚至SMART紀錄和故障紀錄,因為我的實驗沒有辦法分辨),去寫入不同的硬碟。 3. 讀取時則受到寫入時,資料在硬碟之間分散的情況不同影響,最理想時會接近RAID0,最差時就時單一硬碟的讀取速度。 4. 和RAID0唯一的不同是,因為ZFS同時掌握檔案系統和RAID,一顆硬碟故障就不讓你存取故障的zpool,比較不會發生只是排線沒接看不到硬碟就把RAID0掛掉的狀況,只要不去動到裡面的資料,再把硬碟接回去,剛剛ZFS檔案系統中無法讀取的資料,就都會恢復正常。 5. 但是ZFS正常情況下一定將資料分散儲存,萬一是遇到硬碟真的死透了,基本上類似JBOD的組態應該還是沒救。我想,我個人是不會去使用ZFS底下類似JBOD這種組態,多顆硬碟要就用mirror或raidz系列,來確保容錯的功能,當需要使用單一硬碟時,就乾脆單一硬碟形成獨立的zpool,雖然這樣就沒有ZFS的部份好處,但是使用類似JBOD的組態實在有點危險,非常不推薦。 | ||||||||||||
[2] | zpool底下有4顆硬碟,組成raidz1的組態,ZFS寫入讀取行為。 | |||||||||||
zpool | ||||||||||||
raidz1 | ||||||||||||
1 | ||||||||||||
2 | ||||||||||||
3 | ||||||||||||
4 | ||||||||||||
首先是正常情況下的寫入和讀取行為 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料A | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配資料 產生檢查碼P | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||||
online | raidz1 | 1 | online | n/a | A | A1 | A1 | A1 | ||||
2 | online | n/a | A2 | A2 | A2 | |||||||
3 | online | n/a | A3 | A3 | A3 | |||||||
4 | online | n/a | AP | AP | AP | |||||||
資料分割成A1、A2、A3及檢同位查碼AP同時分別寫入4顆硬碟,所以寫入速度是3顆硬碟的合併,寫入行為與RAID5相似。 VM上觀察到,似乎不會立刻從記憶體寫入硬碟,或許是在VM測試的檔案太小了。而在實機測試時檔案的大多了,所以會迅速的寫入硬碟。 用RM刪除檔案時,zpool的空間也不會立刻讓出來,一定要再有其他寫入動作時,才會空出容量,用scrub指令也會。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
online | raidz1 | 1 | online | A1 | A1 | A(1+2+3+P) | A | A1 | ||||
2 | online | A2 | A2 | A2 | ||||||||
3 | online | A3 | A3 | A3 | ||||||||
4 | online | AP | AP | AP | ||||||||
分別從4顆硬碟讀取A1、A2、A3和同位檢查碼AP,還原資料A,所以讀取速度是3顆硬碟的合併,讀取行為與RAID5相似。 用VM測試時從ARC(cache)讀取資料情況明顯,記憶體有資料,硬碟會完全沒有讀取動作。 | ||||||||||||
再來是RAIDZ1(4)組態中有一個硬碟故障的情況下。VM中移除1顆硬碟。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
degraded | raidz1 | 1 | online | A1 | A1 | A(1+2+3) | A | A1 | ||||
2 | online | A2 | A2 | A2 | ||||||||
3 | online | A3 | A3 | A3 | ||||||||
4 | unavail | n/a | n/a | n/a | ||||||||
分別從3顆硬碟讀取A1、A2和A3,還原資料A,所以讀取速度是3顆硬碟的合併,讀取行為與RAID5相似。 用VM測試時從ARC(cache)讀取資料情況明顯,記憶體有資料,硬碟會完全沒有讀取動作。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料B | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配資料 產生檢查碼P | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||||
degraded | raidz1 | 1 | online | A1 | B | B1 | B1 | A1,B1 | ||||
2 | online | A2 | B2 | B2 | A2,B2 | |||||||
3 | online | A3 | B3 | B3 | A3,B3 | |||||||
4 | unavail | n/a | n/a | n/a | n/a | |||||||
這邊的分析出來的寫入行為是用後面重建完成後,恢復正常狀況下的讀取行為 反過來推測出來的。 資料分割成B1、B2、B3同時分別寫入3顆硬碟,所以寫入速度是3顆硬碟的合併,寫入行為與RAID5相似。 光是觀察zpool iostat的訊息裡的剩餘容量,再加上之後重建完成後的讀取資料,就知道zfs並沒有將資料以剩下的3顆硬碟重新分割raidz1的資料,因此在degrade狀態中寫入的資料一樣是沒有容錯的能力。我之前幻想的raidz1保護資料行為並不存在,並不會以剩下的硬碟組成raidz1確保容錯,完 全 沒 有 這 回 事。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
degraded | raidz1 | 1 | online | A1,B1 | B1 | B(1+2+3) | B | A1,B1 | ||||
2 | online | A2,B2 | B2 | A2,B2 | ||||||||
3 | online | A3,B3 | B3 | A3,B3 | ||||||||
4 | unavail | n/a | n/a | n/a | ||||||||
分別從3顆硬碟讀取B1、B2和B3,還原資料B,所以讀取速度是3顆硬碟的合併,讀取行為與RAID5相似。 用VM測試時從ARC(cache)讀取資料情況明顯,記憶體有資料,硬碟會完全沒有讀取動作。 | ||||||||||||
將空白硬碟用zpool replace指令替換故障硬碟,zpool開始進行resilver重建。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
resilver重建 | ||||||||||||
硬碟內資料狀態 | ZFS根據日誌決定必須重建的資料 | 讀取資料 及檢查checksum | 還原資料 | 分配資料 產生檢查碼P | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||
Resilver | raidz1 | 1 | online | A1,B1 | A,B | A1,B1 | A,B | A1,B1 | n/a | A1,B1 | ||
2 | online | A2,B2 | A2,B2 | A2,B2 | n/a | A2,B2 | ||||||
3 | online | A3,B3 | A3,B3 | A3,B3 | n/a | A3,B3 | ||||||
4 | unavail | n/a | n/a | AP,BP | AP,BP | AP,BP | ||||||
可能分別從正常的3顆硬碟讀取資料,還原出A和B,再從A和B重新產生要寫入新硬碟的重建資料,基本上和一般RAID5相似,但是ZFS同樣會根據檔案系統的日誌決定必須重建的資料,所以只會重建degrade期間變動的資料。 和之前的3顆硬碟raidz1組態相同,因為我只能從iostat的讀取寫入資訊來推測ZFS行為,沒辦法直接知道ZFS寫入的詳細順序,所以raidz1比較複雜的重建順序,可能不太正確。 不過有一點疑問未解的部份是,測試當時zpool中有大約512mb的資料,理論上再4顆硬碟組成的raidz1重建時,我推測空白的硬碟應該要重建大約3分之1的資料,也就是約171mb左右的資料,但是resilver的訊息卻顯示resilver了約86mb的資料,也就是6分之1左右,完全不能理解為什麼? 更進一步,在懷疑resilver有問題的情況下,使用zpool scrub指令,會發現剛剛resilver完成的硬碟,出現大量checksum錯誤的訊息,因此scrub自動停止,zpool進入degrade狀態。必須用zpool clear指令清除錯誤,再進行一次zpool scrub,才能完整的同步資料,所以在VM底下resilver 有點問題,會影響資料的安全。 | ||||||||||||
Resilver重建完成後 zpool online | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
online | raidz1 | 1 | online | A1,B1 | A1 | A(1+2+3+P) | A | A1,B1 | ||||
2 | online | A2,B2 | A2 | A2,B2 | ||||||||
3 | online | A3,B3 | A3 | A3,B3 | ||||||||
4 | online | AP,BP | AP | AP,BP | ||||||||
分別從4顆硬碟讀取A1、A2、A3和同位檢查碼AP,還原資料A,所以讀取速度是3顆硬碟的合併,讀取行為與RAID5相似。 雖然有只重建6分之1資料的疑慮,但是讀取測試過程中,zpool status沒有回報任何讀取錯誤。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 讀取資料 | 硬碟內資料狀態 | ||||||||
online | raidz1 | 1 | online | A1,B1 | B1 | B(1+2+3+P) | B | A1,B1 | ||||
2 | online | A2,B2 | B2 | A2,B2 | ||||||||
3 | online | A3,B3 | B3 | A3,B3 | ||||||||
4 | online | AP,BP | BP | AP,BP | ||||||||
分別從4顆硬碟讀取B1、B2、B3和同位檢查碼BP,還原資料B,所以讀取速度是3顆硬碟的合併,讀取行為與RAID5相似。 雖然有只重建6分之1資料的疑慮,但是讀取測試過程中,zpool status沒有回報任何讀取錯誤。 | ||||||||||||
再來是RAIDZ1(4)組態中有2個硬碟故障的情況下。VM中移除2顆硬碟。 | ||||||||||||
zpool status | vdev type | disc | disc status | |||||||||
unavail | n/a | 1 | unavail | |||||||||
2 | unavail | |||||||||||
3 | online | |||||||||||
4 | online | |||||||||||
開機完zpool出現錯誤訊息,unavail的zpool就不會掛上檔案系統,所以根本看不到檔案,更不用說測試了,結果如預期,行為與RAID5相似。 | ||||||||||||
1. 簡單的說明在RAIDZ1由4顆硬碟組態下的行為,就是和3顆硬碟組成RAIDZ1一樣,當然就和RAID5相似了,這邊唯一的重點是,我個人之前所幻想的RAIDZ1會在有硬碟故障時,將資料重新以剩餘正常硬碟組成RAIDZ1以確保資料的容錯能力,完 全 沒 有 這 回 事,實驗結果已經說明了。 2. 只剩下不知道為什麼在官方的ZFS介紹中"ZFS – The Last Word in File Systems",raidz1的stripe width並不是固定大小,說明圖片中的stripe也不是固定依硬碟數量分割,是動態的分配。是我沒半法透過測試瞭解的。 3. 至於resilver的資料量問題,這是VM下第一次測試,使用的方法是關閉VM,修改VM的硬碟組態來模擬,而之前用實體機器測試時我沒有發現過。後來想到之前看過一篇文章,ZFS會對硬碟硬碟使用清除buffer的指令來確保資料有正確完成寫入硬碟。但是在VM 的環境下,會有清除Buffer指令不會正常處理的情形,不管是有VM產生的虛擬硬碟,還是透過VM使用的實體硬碟,只要透過VM存取就會有這樣的情形。但是我現在居然找不到那篇文章,沒有備份,網路上也找不到,所以這只能說是我個人的猜測了。 4. 整理這些資料時,又用VM再測了一次,再次改用zpool offline/online指令來模擬,結果就沒有再發生,或許是沒有關閉VM,所以ZFS完全掌握ARC裡和硬碟內的資料,所以不會有問題。透過VM直接存取實體硬碟有點危險,是個人ZFS測試中額外的心得。 | ||||||||||||
[3] | zpool底下有4顆硬碟,組成兩組mirror的組態,ZFS寫入讀取行 | |||||||||||
zpool | ||||||||||||
mirror | ||||||||||||
1 | ||||||||||||
2 | ||||||||||||
mirror | ||||||||||||
3 | ||||||||||||
4 | ||||||||||||
首先是正常情況下的寫入和讀取行為 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料A | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配vdev資料 | 分配硬碟資料 | 寫入資料 及產生checksum | 硬碟內資料狀態 | |||||||
online | mirror1 | 1 | online | n/a | A | A1 | A1 | A1 | A1 | |||
2 | online | n/a | A1 | A1 | A1 | |||||||
mirror2 | 3 | online | n/a | A2 | A2 | A2 | A2 | |||||
4 | online | n/a | A2 | A2 | A2 | |||||||
A分成A1和A2分別寫入兩組mirror,A1和A2不一定是相同大小,ZFS會動態分配,速度大約是兩顆硬碟同時寫入的水準,行為與RAID10相似。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
online | mirror1 | 1 | online | A1 | A1-1 | A1-1 +A1-2 | A1 | A1+A2 | A | |||
2 | online | A1 | A1-2 | |||||||||
mirror2 | 3 | online | A2 | A2-1 | A2-1 +A2-2 | A2 | ||||||
4 | online | A2 | A2-2 | |||||||||
ZFS將第一組mirror的A1資料,分成兩份再分別從2顆硬碟讀取A1-1 和A1-2,推測ZFS同樣會動態分割A1-1和A1-2的大小,第二組mirror行為相同,檢查checksum之後再加以合併,速度是4顆硬碟合併,行為與RAID0相似。 | ||||||||||||
再來是兩組mirror中,有一組mirror的其中一個硬碟故障的情況下。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
degrade | mirror1 | 1 | unavail | n/a | n/a | A1 | A1 | A1+A2 | A | |||
2 | online | A1 | A1 | |||||||||
mirror2 | 3 | online | A2 | A2-1 | A2-1 +A2-2 | A2 | ||||||
4 | online | A2 | A2-2 | |||||||||
故障mirror的其中一顆硬碟無法讀出資料,所以從另一顆讀取完整的A1,所以A1的讀取速度是一顆硬碟水準。另一組mirror正常,所以從兩顆硬碟分別讀取A2-1及A2-2,檢查checksum之後再加以合併,所以A2的讀取速度是兩顆硬碟合併。但是讀取A1和A2的總和速度受到故障mirror的限制,所以只有兩顆硬碟的合併水準。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料B | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配vdev資料 | 分配硬碟資料 | 寫入資料 及產生checksum | 硬碟內資料狀態 | |||||||
degrade | mirror1 | 1 | unavail | n/a | B | n/a | n/a | n/a | n/a | |||
2 | online | A1 | n/a | A1 | ||||||||
mirror2 | 3 | online | A2 | B | B | B | A2,B | |||||
4 | online | A2 | B | B | A2,B | |||||||
zpool在degrade狀態下寫入全新資料B時,ZFS的特色就出現了。 因為其中一組mirror在degrade狀態下,失去了容錯能力,ZFS會掠過這一組失去容錯能力的mirror,把新資料B寫入另一組容錯能力正常的mirror。B同時寫入正常mirror中的兩顆硬碟,速度是一顆硬碟的水準。同時zpool屬於degarde狀態中,但是新資料B仍然保有容錯能力。 可以發現ZFS在這時犧牲寫入速度,以寫入資料的安全性為第一優先,不會像一般的RAID1+0,因為RAID0部份的關係,在degrade狀態下,新寫入的資料沒有容錯能力。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
degrade | mirror1 | 1 | unavail | n/a | n/a | n/a | n/a | B | B | |||
2 | online | A1 | n/a | |||||||||
mirror2 | 3 | online | A2,B | B-1 | B-1 +B-2 | B | ||||||
4 | online | A2,B | B-2 | |||||||||
因為zpool在degrade狀態下寫入的全新資料B只存在於容錯正常的mirror中。 從正常的mirror讀取B的行為就和單一mirror相同了,從mirror的兩顆硬碟分別讀取動態分割的B-1及B-2,檢查checksum之後再加以合併,速度是兩顆硬碟合併,讀取行為與RAID0相似。 | ||||||||||||
使用空白硬碟接回原來拔下來的故障硬碟位置,zpool開始進行resilver重建。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
Resilver重建 | ||||||||||||
硬碟內資料狀態 | ZFS根據日誌決定必須重建的資料 | 讀取資料 及檢查checksum | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||||
Resilver | mirror1 | 1 | resilver | n/a | A1 | n/a | A1 | A1 | ||||
2 | online | A1 | A1 | n/a | A1 | |||||||
mirror2 | 3 | online | A2,B | n/a | n/a | A2,B | ||||||
4 | online | A2,B | n/a | n/a | A2,B | |||||||
ZFS同樣會根據檔案系統的日誌決定必須重建的資料,所以只會重建degrade期間變動的資料,新硬碟只缺少A1,而故障期間的新資料B已經在正常的mirror中有容錯,所以ZFS不會再針對B進行重建,所以只寫入A1進入新硬碟,不會重建整個zpool下的資料,大幅縮短重建時間,這也是ZFS的一大特點,與一般RAID和檔案系統各自獨立的情況下是辦不到的。重建速度在理想情況下就是單顆硬碟的寫入速度上限。 我再重複提一次的是,ZFS再遇到硬碟故障時,會因為故障方式不同,以及換上新硬碟時,是同一個SATA接口互換硬碟,還是用額外的SATA接口接上重建用的新硬碟,都會讓重建行為不同,因為內容複雜,我打算另外寫一篇文章說明。 | ||||||||||||
Resilver重建完成後 zpool online | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取 資料 | |||||||
online | mirror1 | 1 | online | A1 | A1-1 | A1-1 +A1-2 | A1 | A1+A2 | A | |||
2 | online | A1 | A1-2 | |||||||||
mirror2 | 3 | online | A2,B | A2-1 | A2-1 +A2-2 | A2 | ||||||
4 | online | A2,B | A2-2 | |||||||||
ZFS將第一組mirror的A1資料,分成兩份再分別從2顆硬碟讀取A1-1 和A1-2,推測ZFS同樣會動態分割A1-1和A1-2的大小,第二組mirror行為相同,檢查checksum之後再加以合併,速度是4顆硬碟合併,行為與RAID0相似。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
online | mirror1 | 1 | online | A1 | n/a | n/a | n/a | B | B | |||
2 | online | A1 | n/a | |||||||||
mirror2 | 3 | online | A2,B | B-1 | B-1 +B-2 | B | ||||||
4 | online | A2,B | B-2 | |||||||||
因為資料B只存在於單一的mirror中。 從正常的mirror讀取B的行為就和單一mirror相同了,從mirror的兩顆硬碟分別讀取動態分割的B-1及B-2,檢查checksum之後再加以合併,速度是兩顆硬碟合併,讀取行為與RAID0相似。 | ||||||||||||
假如要簡單的說明ZFS在兩組mirror組態下的寫入和讀取行為,正常下寫入像RAID1+0讀取像RAID0,異常下寫入和讀取則要看資料配置的狀況,但是可以發現ZFS以確保寫入資料的安全為第一優先。 再進一步,萬一是壞兩顆硬碟,剛好兩個mirror各壞一顆硬碟,全壞在同一組mirror的情況下,ZFS的寫入和讀取行為會如何變化,也很值得用VM測試一下。 | ||||||||||||
再來是兩組mirror中,各有一個硬碟故障的情況下,總共故障兩顆硬碟,使用offline指令模擬。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取 資料 | |||||||
degraded | mirror1 | 1 | unavail | n/a | n/a | A1 | A1 | A1+A2 | A | |||
2 | online | A1 | A1 | |||||||||
mirror2 | 3 | unavail | n/a | n/a | A2 | A2 | ||||||
4 | online | A2,B | A2 | |||||||||
因為兩組mirror的都有一顆硬碟故障,第一組mirror正常的硬碟讀取完整的A1,所以A1的讀取速度是一顆硬碟水準。第二組mirror狀況相同,從正常的硬碟讀取完整的A2,所以A2的讀取速度是一顆硬碟水準。讀取A1和A2的總和速度受只有兩顆硬碟的合併水準。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取 資料 | |||||||
degraded | mirror1 | 1 | unavail | n/a | n/a | n/a | n/a | B | B | |||
2 | online | A1 | n/a | |||||||||
mirror2 | 3 | unavail | n/a | n/a | B | B | ||||||
4 | online | A2,B | B | |||||||||
因為資料只存在於第二組mirror,所以從第二組mirror正常的硬碟讀取完整的B,所以B的讀取速度是一顆硬碟水準。讀取B的總和速度受只有一顆硬碟的水準。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
寫入資料C | ||||||||||||
硬碟內資料狀態 | 寫入資料 | 分配vdev資料 | 分配硬碟資料 | 寫入資料 及產生checksum | 硬碟內資料狀態 | |||||||
degrade | mirror1 | 1 | unavail | n/a | C | C1 | n/a | n/a | n/a | |||
2 | online | A1 | C1 | C1 | A1,C1 | |||||||
mirror2 | 3 | unavail | n/a | C2 | n/a | n/a | n/a | |||||
4 | online | A2,B | C2 | C2 | A2,B,C2 | |||||||
VM中的測試結果很特別,雖然兩組mirror2都沒有容錯能力,但是mirror2因為資料較多剩餘空間比較少,我認為資料會先寫入mirror1。但是VM中的測試結果卻超乎意料之外,zpool iostat顯示是先把資料寫入mirror2,直到mirror2沒有空間後才開始出現寫入mirror1的動作。ZFS確實是動態分割寫入的資料但是分配原則再這種其況下無法理解。 我用不同容量的VM硬碟測了兩次,結果都相同,似乎是ZFS會硬碟online及offline的故障紀錄,去避開有問題的硬碟,而不是根據剩餘容量,但是ZFS判斷有故障風險的硬碟原則,在VM中一直測試不出確定的結果。 因為重新建立的zpool,最先出現offline紀錄過的硬碟和mirror(我用手動offline指令達成),兩組mirror2都沒有容錯能力時,ZFS似乎會優先避免寫入資料。要改變優先寫入的硬碟,只能透過重新建立zpool,zpool clear指令,不會改變這種寫入行為。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料C | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取 資料 | |||||||
degraded | mirror1 | 1 | unavail | n/a | n/a | C1 | C1 | C1+C2 | C | |||
2 | online | A1,C1 | C1 | |||||||||
mirror2 | 3 | unavail | n/a | n/a | C2 | C2 | ||||||
4 | online | A2,B,C2 | C2 | |||||||||
因為根據前面的寫入測試,資料C很明顯不是平均分配在兩組mirror的C1和C2之中,所以讀取集中在其中一組mirror,讀取速度自然接近單一硬碟。這就是ZFS動態分配資料對讀取效能的影響。 | ||||||||||||
將offline的硬碟重新online,進行resilver | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
Resilver重建 | ||||||||||||
硬碟內資料狀態 | ZFS根據日誌決定必須重建的資料 | 讀取資料 及檢查checksum | 寫入資料 及產生checksum | 硬碟內資料狀態 | ||||||||
Resilver | mirror1 | 1 | resilver | n/a | A,B,C | n/a | A1,C1 | A1,C1 | ||||
2 | online | A1,C1 | A1,C1 | n/a | A1,C1 | |||||||
mirror2 | 3 | resilver | n/a | n/a | A2,B,C2 | A2,B,C2 | ||||||
4 | online | A2,B,C2 | A2,B,C2 | n/a | A2,B,C2 | |||||||
ZFS同樣會根據檔案系統的日誌決定必須重建的資料,所以只會重建degrade期間變動的資料。因為兩組mirror都有故障,所以所有資料都需要重建,資料A、C分佈在兩組mirror,所兩組mirror都有重建動作,資料B只存在mirror2,所以資料B的重建只發生在mirror2。 | ||||||||||||
Resilver重建完成後 zpool online | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料A | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
online | mirror1 | 1 | online | A1,C1 | A1-1 | A1-1 +A1-2 | A1 | A1+A2 | A | |||
2 | online | A1,C1 | A1-2 | |||||||||
mirror2 | 3 | online | A2,B,C2 | A2-1 | A2-1 +A2-2 | A2 | ||||||
4 | online | A2,B,C2 | A2-2 | |||||||||
資料A是在zpool正常的情況下寫入,所以是平均分配在兩組mirror,速度是4顆硬碟合併,行為與RAID0相似。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料B | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
online | mirror1 | 1 | online | A1,C1 | n/a | n/a | n/a | B | B | |||
2 | online | A1,C1 | n/a | |||||||||
mirror2 | 3 | online | A2,B,C2 | B-1 | B-1 +B-2 | B | ||||||
4 | online | A2,B,C2 | B-2 | |||||||||
資料B是在一組mirror1故障情況下寫入,所以只存在mirror2中,速度是2顆硬碟合併,行為與RAID0相似。 | ||||||||||||
zpool status | vdev type | disc | disc status | (順序由左至右) | ||||||||
讀取資料C | ||||||||||||
硬碟內資料狀態 | 讀取資料 及檢查checksum | 合併 vdev 硬碟資料 | 輸出 mirror 資料 | 合併 vdev 資料 | 讀取資料 | |||||||
online | mirror1 | 1 | online | A1,C1 | C1-1 | C1-1 +C1-2 | C1 | C1+C2 | C | |||
2 | online | A1,C1 | C1-2 | |||||||||
mirror2 | 3 | online | A2,B,C2 | C2-1 | C2-1 +C2-2 | C2 | ||||||
4 | online | A2,B,C2 | C2-2 | |||||||||
資料C是在兩組mirror都有故障情況下寫入,雖然兩組mirror都有分配到寫入資料,但C1和C2並不是平均分配,而是集中寫入在ZFS系統認定比較安全的mirror中,所以讀取資料必須等待單一mirror讀取資料,所以速度接近2顆硬碟合併,行為與RAID0相似。 | ||||||||||||
與之前用實體硬碟測試相同的部份 假如要簡單的說明ZFS在兩組mirror組態下的寫入和讀取行為,正常下寫入像RAID1+0讀取像RAID0,異常下寫入和讀取則要看資料配置的狀況,但是可以發現ZFS以確保寫入資料的安全為第一優先。 再進一步,萬一是壞兩顆硬碟,剛好兩個mirror各壞一顆硬碟,全壞在同一組mirror的情況下,ZFS的寫入和讀取行為會如何變化,也很值得用VM測試一下。 使用VM測試新增的部份 1 兩個mirror可以視為,兩個硬碟組成的JBOD組態。Vdev的mirror掛掉就等於JBOD中的硬碟掛掉。所以在瞭解ZFS在JBOD和mirror組態的各自的特性後,就可以發現zpool下有兩組mirror下的寫入讀取行為,是可以預測的,實驗結果也符合預期。 2 但是ZFS寫入資料到兩組vdev mirror的優先順序就沒辦法預測了,很顯然除了平均分配外,故障紀錄也會影響寫入行為,這我真的不知道如何測試了,尤其是有些行為在VM中沒辦法模擬,像是直接拔硬碟的線等等。 |
沒有留言:
張貼留言