close

 

文、小州老師

小州老師個人檔案

Sun 的 ZFS 優秀的功能我想網路上看到不少,不過一直沒時間去裝一套 OpenSolaris 系統來測試,不過有一群 developer 實做成為 Filesystem in userspace (FUSE) 下的 zfs 的支援,所以 Linux Kernel 不支援 zfs 還是可以拿來使用。

那要使用哪個 Linux 版本呢,我想手上本身挑自己的 Mandriva cooker 機器,用 Cooker 好處就是每次都可以用最新的程式套件,畢竟是一個發展用的版本所以測新的程式軟體就很方便不過好消息是,其實目前的 Fedora Linux 11 版本開始也納入支援,所以只要安裝上 zfs-fuse 套件包就可以使用了。不過下面我以目前我手上的 Mandriva Cooker 版本當說明環境。

先使用 urpmi 安裝上 zfs-fuse 套件後即可使用,該套件安裝好後使用 rpm -ql 檢視可以看到一些檔案清單

/etc/bash_completion.d/zfs-fuse
/etc/rc.d/init.d/zfs-fuse
/usr/sbin/zdb
/usr/sbin/zfs
/usr/sbin/zfs-fuse
/usr/sbin/zpool
/usr/sbin/ztest
/usr/share/doc/zfs-fuse
/usr/share/doc/zfs-fuse/BUGS
/usr/share/doc/zfs-fuse/CHANGES
/usr/share/doc/zfs-fuse/HACKING
/usr/share/doc/zfs-fuse/INSTALL
/usr/share/doc/zfs-fuse/LICENSE
/usr/share/doc/zfs-fuse/README
/usr/share/doc/zfs-fuse/STATUS
/usr/share/doc/zfs-fuse/TESTING
/usr/share/doc/zfs-fuse/TODO
/usr/share/man/man1/zdb.1.lzma
/usr/share/man/man1/zfs.1.lzma
/usr/share/man/man1/zpool.1.lzma


先執行啟動 /etc/init.d/zfs-fuse 這個服務才可以開始使用 zfs 的相關支援。而該服務啟動後,可以看到系統一個名稱為 zfs-fuse 的 daemon 正在運作。然後跑一下 zfs 提供的兩個主要大命令,zpool 與 zfs 這兩個程式看一下輸出:

missing command
usage: zpool command args …
where ‘command’ is one of the following:

create [-fn] [-o property=value] …
[-O file-system-property=value] …
[-m mountpoint] [-R root]

destroy [-f]

add [-fn]

remove

list [-H] [-o property[,...]] [pool] …
iostat [-v] [pool] … [interval [count]]
status [-vx] [pool] …

online

offline [-t]

clear
[device]

attach [-f]

detach

replace [-f]
[new-device]

scrub [-s]

import [-d dir] [-D]
import [-o mntopts] [-o property=value] …
[-d dir | -c cachefile] [-D] [-f] [-R root] -a [-v]
import [-o mntopts] [-o property=value] …
[-d dir | -c cachefile] [-D] [-f] [-R root]
[newpool]
export [-f]

upgrade
upgrade -v
upgrade [-V version] <-a | pool …>

history [-il] [
] …
get <”all” | property[,...]>

set


下面這是 zfs 命令輸出:

missing command
usage: zfs command args …
where ‘command’ is one of the following:

create [-p] [-o property=value] …
create [-ps] [-b blocksize] [-o property=value] … -V
destroy [-rRf]

snapshot [-r] [-o property=value] …
rollback [-rRf]
clone [-p] [-o property=value] …
promote
rename
rename -p
rename -r
list [-rH][-d max] [-o property[,...]] [-t type[,...]] [-s property] …
[-S property] … [filesystem|volume|snapshot] …

set

get [-rHp] [-d max] [-o field[,...]] [-s source[,...]]
<”all” | property[,...]> [filesystem|volume|snapshot] …
inherit [-r]

upgrade [-v]
upgrade [-r] [-V version] <-a | filesystem …>
userspace [-hniHp] [-o field[,...]] [-sS field] … [-t type[,...]]

groupspace [-hniHpU] [-o field[,...]] [-sS field] … [-t type[,...]]

mount
mount [-vO] [-o opts] <-a | filesystem>
unmount [-f] <-a | filesystem|mountpoint>
share <-a | filesystem>
unshare [-f] <-a | filesystem|mountpoint>

send [-R] [-[iI] snapshot]
receive [-vnF]
receive [-vnF] -d

allow
allow [-ldug] <”everyone”|user|group>[,...]
[,...]

allow [-ld] -e
[,...]
allow -c
[,...]
allow -s @setname
[,...]

unallow [-rldug] <”everyone”|user|group>[,...]
[
[,...]]
unallow [-rld] -e [
[,...]]
unallow [-r] -c [
[,...]]
unallow [-r] -s @setname [
[,...]]

Each dataset is of the form: pool/[dataset/]*dataset[@name]

For the property list, run: zfs set|get

For the delegated permission list, run: zfs allow|unallow



由於這台機器上沒有其他可用的硬碟分割區空間,所以只好使用 dd 建立幾個大檔案模擬實際上的可用區塊空間。

[root@info /]# mkdir /zfs
[root@info /]# dd if=/dev/zero of=/zfs/zfs-1.dat bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.594376 s, 176 MB/s
[root@info /]# dd if=/dev/zero of=/zfs/zfs-2.dat bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.671803 s, 156 MB/s


分別在建立 /zfs 目錄建立 zfs-1.dat 與 zfs-2.dat 檔案,每個檔案分別為 100MB 的大小。下面繼續使用 zpool 建立 pool 空間:

[root@info /]# zpool create test /zfs/zfs-1.dat /zfs/zfs-2.dat


然後使用 zpool list 看一下建立的結果:

[root@info /]# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
test 191M 78K 191M 0% ONLINE -

 

目前的 pool 空間為 191MB。使用 zpool status 看一下詳細狀態:

[root@info /]# zpool status
pool: test
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
test ONLINE 0 0 0
/zfs/zfs-1.dat ONLINE 0 0 0
/zfs/zfs-2.dat ONLINE 0 0 0

errors: No known data errors

目前初步 pool 已經建立完成,下面就可以使用 zfs 該命令建立實際可用的空間。

[root@info /]# zfs create test/n1
[root@info /]# zfs create test/n2
[root@info /]#
[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 134K 159M 23K /test
test/n1 21K 159M 21K /test/n1
test/n2 21K 159M 21K /test/n2

前面建立的 pool 名稱為 test,所以使用 zfs create 時候需要繼續指定使用 test 這個 pool 名稱,然後依序建立 n1 與 n2 這兩個檔案系統項目。不過目前預設掛載點是在 /test 內的 n1 與 n2,實際使用上不一定都位於 /test 目錄內使用,所以調整一下掛載點的配置:

[root@info /]# zfs set mountpoint=/n1 test/n1
[root@info /]# zfs set mountpoint=/n2 test/n2
[root@info /]#
[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 152K 159M 23K /test
test/n1 21K 159M 21K /n1
test/n2 21K 159M 21K /n2

所以目前指定到 /n1 與 /n2 這兩個掛載點的目錄位置上。使用 df -h 檢視也可以看到已經掛入的資訊:

[root@info /]# df -h | grep test
test 159M 21K 159M 1% /test
test/n1 159M 21K 159M 1% /n1
test/n2 159M 21K 159M 1% /n2

 

空間來看,其實 n1 與 n2 都是共用 159M 的 pool 空間,所以磁碟空間分配上會非常有效率,這就與 Linux 上面使用 LVM 的架構有所不同。
產生一些檔案佔用 n1 的檔案系統空間:

[root@info /]# for((i=1;i<100;i++)); do cat /etc/termcap >> /n1/file1.dat; done
[root@info /]#
[root@info /]# ls -lh /n1/
total 66M
-rw-r–r– 1 root root 67M Jan 21 05:32 file1.dat
[root@info /]#

然後使用 zfs list 檢視結果:

[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 66.9M 92.1M 24K /test
test/n1 66.6M 92.1M 66.6M /n1
test/n2 21K 92.1M 21K /n2
[root@info /]#

 

可以看出來 test/n1 的檔案系統空間已經被佔用了。

[root@info /]# df -h | grep test
test 93M 21K 93M 1% /test
test/n1 159M 67M 93M 42% /n1
test/n2 93M 21K 93M 1% /n2

 

下面測試 zfs 透通壓縮的支援功能:

[root@info /]# zfs set compression=on test/n2
[root@info /]#
[root@info /]# for((i=1;i<100;i++)); do cat /etc/termcap >> /n2/file1.dat; done
[root@info /]#
[root@info /]# ls -lh /n2/file1.dat
-rw-r–r– 1 root root 67M Jan 21 05:37 /n2/file1.dat
[root@info /]#

 

目前只有針對 test/n2 設定壓縮功能,然後與前面一樣大小內容的檔案提供比較測試,然後再次 zfs list 查看結果:

[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 110M 48.9M 21K /test
test/n1 66.6M 48.9M 66.6M /n1
test/n2 43.0M 48.9M 43.0M /n2
[root@info /]#

 

用 df 再次確認一下:

[root@info n1]# df -h | grep test
test 44M 21K 44M 1% /test
test/n1 111M 67M 44M 61% /n1
test/n2 92M 49M 44M 53% /n2
[root@info n1]#

 

所以可以發現到相同的檔案,但是產生佔用的空間相差至少 20MB 空間。不過為了確認兩個檔案都一樣的內容,使用 md5sum 確認一下更好。

[root@info /]# md5sum /n1/file1.dat /n2/file1.dat
30e4f82d620e3bdc3999ce96f5c93cde /n1/file1.dat
30e4f82d620e3bdc3999ce96f5c93cde /n2/file1.dat
[root@info /]#

 

下面來玩玩新增 pool 的空間作法,所以還是用 dd 建立大檔並使用 zpool 加入使用。

[root@info /]# dd if=/dev/zero of=/zfs/zfs-3.dat bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.534388 s, 196 MB/s
[root@info /]#
[root@info /]# zpool add test /zfs/zfs-3.dat
[root@info /]#
[root@info /]# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
test 286M 115M 171M 40% ONLINE -
[root@info /]#

 

目前可以看出 pool 的空間已經成長到達 286M,而之前為 159MB。那現在使用 zfs 命令檢視旗下檔案系統的狀態:

[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 115M 139M 21K /test
test/n1 66.6M 139M 66.6M /n1
test/n2 48.2M 139M 48.2M /n2
[root@info /]#

 

所以 test 這個 pool 空間變大後,旗下的檔案系統可用空間也直接變大了。使用 df -h 檢視應該更清楚:

[root@info /]# df -h | grep test
test 140M 21K 140M 1% /test
test/n1 206M 67M 140M 33% /n1
test/n2 188M 49M 140M 26% /n2

 

來測試 clone 功能…

[root@info /]# zfs clone test/n1@20100121 test/n3
[root@info /]#
[root@info /]# zfs set mountpoint=/n3 test/n3
[root@info /]#
[root@info /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 115M 139M 21K /test
test/n1 66.6M 139M 66.6M /n1
test/n2 48.2M 139M 48.2M /n2
test/n3 16K 139M 66.6M /n3

 

目前的 test1/n1 另外 clone 複製一份成為 test/n3 提供使用,所以 test3/n3 內容會與 test1/n2 完全一樣。其中使用 clone 命令,來源的檔案系統是 test/n1 沒錯,但是後面要多一個 @ 敘述,這邊就指定一個時間紀錄點應對比較好記。

[root@info /]# df -h | grep test
test 140M 21K 140M 1% /test
test/n1 206M 67M 140M 33% /n1
test/n2 188M 49M 140M 26% /n2
test/n3 206M 67M 140M 33% /n3

 

透過 df 的結果可以確認空間結果都相同,當然 /n3 內也會有原本的檔案項目。

不過呢… 詳細看一次剛剛內容,我驚訝的是上面那個 zfs list 輸出時候顯示 test/n3 佔用空間為 16K,竟然與 test/n1 佔用空間不一樣,莫非厲害到可以紀錄相同檔案的空間?那我修改一下 /n3 該目錄內的檔案,看看結果會如何變化…

[root@info ~]# ls -lh /n1/file1.dat
-rw-r–r– 1 root root 67M Jan 21 05:46 /n1/file1.dat
[root@info ~]#
[root@info ~]# cat /n1/file1.dat >> /n3/file1.dat
[root@info ~]#
[root@info ~]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 174M 80.7M 21K /test
test/n1 66.6M 80.7M 66.6M /n1
test/n2 48.2M 80.7M 48.2M /n2
test/n3 66.6M 72.0M 133M /n3
[root@info ~]#
[root@info ~]# df -h | grep test
test 73M 21K 73M 1% /test
test/n1 139M 67M 73M 49% /n1
test/n2 121M 49M 73M 41% /n2
test/n3 206M 133M 73M 65% /n3
[root@info ~]#
[root@info ~]# ls -lh /n3/file1.dat
-rw-r–r– 1 root root 133M Jan 21 06:31 /n3/file1.dat

 

這時候我發現神奇事情…. /n3/file1.dat 的確變成 133M 的大小,但是檢視 test/n3 本身 zfs 的佔用空間卻只有 66.6M,這表示 zfs 本身已經聰明到紀錄檔案本身實際上還共用哪些區塊空間,真是令人感覺驚豔….. 所以說往後透過 clone 的命令產生的新的檔案系統,其實速度上會非常的快,因為只是標注使用的區塊資訊而非真正去複製一份資料內容。

不過我剛剛是使用 >> 方式附加的,所以只有紀錄附加上資料的資訊,那現在我用 hexedit 命令直接開啟 /n3/file1.dat 檔案編修內容,然後看一下最終結果…..

[root@info n3]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
test 183M 71.4M 21K /test
test/n1 66.6M 71.4M 66.6M /n1
test/n2 48.2M 71.4M 48.2M /n2
test/n3 67.2M 71.4M 133M /n3

 

可以觀察到 test/n3 本身實際佔用空間變大了,這再次證明 zfs 真的非常優秀…. 對於磁碟空間的分配管理機制有獨到的設計,更能夠充分發揮磁碟空間的使用。而繼續看一下 zfs 的 manpage 其實就已經有提到:

Clones

A clone is a writable volume or file system whose initial contents are the same as another dataset. As with snapshots, creating a clone is nearly instantaneous, and initially consumes no additional space.

原來這是可以讀寫版的 snapshot 功能… 而 snapshot 命令依據 manpage 說明,本身為唯讀的性質。

初探測試 Part1 先到這邊….

 

本期電子報首頁

聯成焦點:「我的求職大 測試」測試你的職場競爭力

 聯成電腦報馬仔:最推 課、新報導...聯成有啥新鮮事?

聯成電腦精彩人物:關於 一個創作者~專訪林奕辰老師

聯成電腦證照新知:如何 準備ACA國際認證-Flash篇

聯成電腦技術前線:動物 插畫教學

arrow
arrow
    創作者介紹
    創作者 聯成電腦 的頭像
    聯成電腦

    聯成電腦-讓你價值連城

    聯成電腦 發表在 痞客邦 留言(0) 人氣()