2014年3月22日土曜日

ZFS on Linux の vdev_id

ZFS on Linux が認識するデバイスパスは、デフォルトでは /dev/disk/by-id が使われます。次のような具合です。
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# zpool status
  pool: tank4
 state: ONLINE
  scan: scrub repaired 0 in 1h18m with 0 errors on Sat Mar 15 20:39:47 2014
config:

 NAME                                                        STATE     READ WRITE CKSUM
 tank4                                                       ONLINE       0     0     0
   mirror-0                                                  ONLINE       0     0     0
     ata-HITACHI_HTS725050A9A364_xxxxxxxxxxxxxxxxxxxx-part1  ONLINE       0     0     0
     ata-HGST_HTS721010A9E630_yyyyyyyyyyyyyy-part1           ONLINE       0     0     0

errors: No known data errors
[root@hoge ~]# ls -l /dev/disk/by-id/ata-H*-part1
lrwxrwxrwx 1 root root 10 Mar 22 15:24 /dev/disk/by-id/ata-HGST_HTS721010A9E630_yyyyyyyyyyyyyy-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Mar 22 15:24 /dev/disk/by-id/ata-HITACHI_HTS725050A9A364_xxxxxxxxxxxxxxxxxxxx-part1 -> ../../sdc1
sdX なんかを使ってはよろしくない(ずれるから)のは分かりますが、どうにも長くて、特に同じ種類のディスクを使っていると個体を識別し難い(何番目のベイのディスクか不明瞭)と思っていました。
ZFS on Linux には、vdev_id というツールが用意されていて、この長いパスに別名(alias)を付与することができるようです。/etc/zfs/vdev_id.conf に次のように指定します。
#     by-vdev
#     name     fully qualified or base name of device link
alias  HITACHI_500G  ata-HITACHI_HTS725050A9A364_xxxxxxxxxxxxxxxxxxxx
alias  HGST___1000G  ata-HGST_HTS721010A9E630_yyyyyyyyyyyyyy
設定して再起動すると、/dev/disk/by-vdev というデバイスパスが生成されるようになります。
[root@hoge ~]# ls -l /dev/disk/by-vdev/H*-part1
lrwxrwxrwx 1 root root 10 Mar 22 15:24 /dev/disk/by-vdev/HGST___1000G-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Mar 22 15:24 /dev/disk/by-vdev/HITACHI_500G-part1 -> ../../sdc1
いったんプールを export してから、-d オプションを使って import し直せば、この便利な名前が使われるようになります。
[root@hoge ~]# zpool export tank4
[root@hoge ~]# zpool import -d /dev/disk/by-vdev tank4
[root@hoge ~]# zpool status tank4
  pool: tank4
 state: ONLINE
  scan: scrub repaired 0 in 1h18m with 0 errors on Sat Mar 15 20:39:47 2014
config:

 NAME                    STATE     READ WRITE CKSUM
 tank4                   ONLINE       0     0     0
   mirror-0              ONLINE       0     0     0
     HITACHI_500G-part1  ONLINE       0     0     0
     HGST___1000G-part1  ONLINE       0     0     0

errors: No known data errors
うまく名前を付与すれば物理的な接続(SATA portの何番に接続したディスクか?ベイの何段目のディスクか?等)も表現できて便利と思います。短めの名前をつければ、コンソール画面(横80桁)での操作時に、折り返し表示にならずに済むことにもなります。

2014年3月16日日曜日

3つのOSでZFSの性能を比較

以前にも測定したことがありますが、最近 FreeBSD 10.0 がリリースされたので、日常的操作(コピー、シーケンシャルREAD)で性能比較を行ってみました。
2015-04-18追記、ふたたび比較実験しました。

比較は、
・CentOS 6.5 + ZFS on Linux 0.6.2
・OpenIndiana 151a9
(最近ひっそりとアップデートされた。ただし iso 提供は無し)
・FreeBSD 10.0
の3つの OS で行いました。マシン環境は次の通りです。3つの OS をマルチブートできるようにしてあります。

・lenovo ThinkPad T510
・CPU Intel Core i7 M620 2.67GHz
・MEM 8GB
・OS ディスク R2021D
(Plextor M5M 256GB SSD 2枚によるRAID1)
・ZFS pool (HGST HTS721010A9E630 7200rpm SATA 1TB +
 HITACHI HTS725050A9A634 7200rpm SATA 500GB による mirror構成)
 ※補足:HGST 1T を 2nd HDD ベイに搭載、HITACHI 500G は eSATA 接続で、約400G のパーティションでミラー

まずは、ファイルコピーです。実験データには、CentOS 6 の OS バックアップイメージを使っています。
root@hoge:~# uname -a
SunOS hoge 5.11 oi_151a9 i86pc i386 i86pc Solaris
root@hoge:~# zpool import tank4
root@hoge:~# zpool list
NAME    SIZE  ALLOC   FREE  EXPANDSZ    CAP  DEDUP  HEALTH  ALTROOT
rpool  11.6G  9.57G  2.06G         -    82%  1.00x  ONLINE  -
tank4   368G   268G  99.7G         -    72%  1.00x  ONLINE  -
root@hoge:~# zpool status tank4
  pool: tank4
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
 still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
 the pool may no longer be accessible by software that does not support
 the features. See zpool-features(5) for details.
  scan: scrub repaired 0 in 1h18m with 0 errors on Sat Mar 15 20:39:47 2014
config:

 NAME          STATE     READ WRITE CKSUM
 tank4         ONLINE       0     0     0
   mirror-0    ONLINE       0     0     0
     c5t3d0p1  ONLINE       0     0     0
     c5t1d0p1  ONLINE       0     0     0

errors: No known data errors
root@hoge:~# cd /tank4/backup
root@hoge:/tank4/backup# ls -l m5m.sda6.dump 
-rw-r--r-- 1 root root 9207209203 2014-02-22 21:51 m5m.sda6.dump
root@hoge:/tank4/backup# cp m5m.sda6.dump m5m.sda6.dump-copied-on-oi151a9

real 3m44.857s
user 0m0.056s
sys 0m16.702s
root@hoge:/tank4/backup# ls -l m5m.sda6.dump*
-rw-r--r-- 1 root root 9207209203 2014-02-22 21:51 m5m.sda6.dump
-rw-r--r-- 1 root root 9207209203 2014-03-16 13:55 m5m.sda6.dump-copied-on-oi151a9
root@hoge:/tank4/backup# cd
root@hoge:~# zpool export tank4
root@hoge:~ # uname -a
FreeBSD hoge 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
root@hoge:~ # zpool import tank4
root@hoge:~ # zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   277G  91.1G    75%  1.00x  ONLINE  -
root@hoge:~ # zpool status
  pool: tank4
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
 still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
 the pool may no longer be accessible by software that does not support
 the features. See zpool-features(7) for details.
  scan: scrub repaired 0 in 1h18m with 0 errors on Sat Mar 15 20:39:47 2014
config:

 NAME                                    STATE     READ WRITE CKSUM
 tank4                                   ONLINE       0     0     0
   mirror-0                              ONLINE       0     0     0
     diskid/DISK-xxxxxxxxxxxxxxxxxxxxs1  ONLINE       0     0     0
     diskid/DISK-yyyyyyyyyyyyyys1        ONLINE       0     0     0

errors: No known data errors
root@hoge:~ # cd /tank4/backup
root@hoge:/tank4/backup # ls -l m5m*
-rw-r--r--  1 root  wheel  9207209203 Feb 22 21:51 m5m.sda6.dump
-rw-r--r--  1 root  wheel  9207209203 Mar 16 13:55 m5m.sda6.dump-copied-on-oi151a9
root@hoge:/tank4/backup # time cp m5m.sda6.dump m5m.sda6.dump-copied-on-freebsd10.0
0.007u 4.455s 4:14.75 1.7% 21+174k 70801+2io 0pf+0w
root@hoge:/tank4/backup # ls -l m5m*
-rw-r--r--  1 root  wheel  9207209203 Feb 22 21:51 m5m.sda6.dump
-rw-r--r--  1 root  wheel  9207209203 Mar 16 14:09 m5m.sda6.dump-copied-on-freebsd10.0
-rw-r--r--  1 root  wheel  9207209203 Mar 16 13:55 m5m.sda6.dump-copied-on-oi151a9
root@hoge:/tank4/backup # cd
root@hoge:~ # zpool export tank4
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# zpool import tank4
[root@hoge ~]# zpool status
  pool: tank4
 state: ONLINE
  scan: scrub repaired 0 in 1h18m with 0 errors on Sat Mar 15 20:39:47 2014
config:

 NAME                                                        STATE     READ WRITE CKSUM
 tank4                                                       ONLINE       0     0     0
   mirror-0                                                  ONLINE       0     0     0
     ata-HITACHI_HTS725050A9A364_xxxxxxxxxxxxxxxxxxxx-part1  ONLINE       0     0     0
     ata-HGST_HTS721010A9E630_yyyyyyyyyyyyyy-part1           ONLINE       0     0     0

errors: No known data errors
[root@hoge ~]# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   285G  82.6G    77%  1.00x  ONLINE  -
[root@hoge ~]# cd /tank4/backup
[root@hoge backup]# ls -l m5m*
-rw-r--r-- 1 root root 9207209203 Feb 22 21:51 m5m.sda6.dump
-rw-r--r-- 1 root root 9207209203 Mar 16 14:09 m5m.sda6.dump-copied-on-freebsd10.0
-rw-r--r-- 1 root root 9207209203 Mar 16 13:55 m5m.sda6.dump-copied-on-oi151a9
[root@hoge backup]# time cp m5m.sda6.dump m5m.sda6.dump-copied-on-centos6

real 3m29.308s
user 0m0.038s
sys 0m6.764s
[root@hoge backup]# ls -l m5m*
-rw-r--r-- 1 root root 9207209203 Feb 22 21:51 m5m.sda6.dump
-rw-r--r-- 1 root root 9207209203 Mar 16 14:21 m5m.sda6.dump-copied-on-centos6
-rw-r--r-- 1 root root 9207209203 Mar 16 14:09 m5m.sda6.dump-copied-on-freebsd10.0
-rw-r--r-- 1 root root 9207209203 Mar 16 13:55 m5m.sda6.dump-copied-on-oi151a9
[root@hoge backup]# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   294G  74.0G    79%  1.00x  ONLINE  -

次に、シーケンシャルREAD (ddコマンド利用) です。
キャッシュの影響を避けるため、再起動&zpool import 直後に実行しています。
root@hoge:~# uname -a
SunOS hoge 5.11 oi_151a9 i86pc i386 i86pc Solaris
root@hoge:~# dd if=/tank4/backup/m5m.sda6.dump-copied-on-oi151a9 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 106.582 s, 86.4 MB/s
root@hoge:~# dd if=/tank4/backup/m5m.sda6.dump-copied-on-freebsd10.0 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 115.16 s, 80.0 MB/s
root@hoge:~# dd if=/tank4/backup/m5m.sda6.dump-copied-on-centos6 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 114.334 s, 80.5 MB/s
root@hoge:~ # uname -a
FreeBSD hoge 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
root@hoge:~ # dd if=/tank4/backup/m5m.sda6.dump-copied-on-oi151a9 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes transferred in 105.113849 secs (87592732 bytes/sec)
root@hoge:~ # dd if=/tank4/backup/m5m.sda6.dump-copied-on-freebsd10.0 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes transferred in 114.760721 secs (80229621 bytes/sec)
root@hoge:~ # dd if=/tank4/backup/m5m.sda6.dump-copied-on-centos6 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes transferred in 113.732792 secs (80954745 bytes/sec)
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# dd if=/tank4/backup/m5m.sda6.dump-copied-on-oi151a9 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 64.9959 s, 142 MB/s
[root@hoge ~]# dd if=/tank4/backup/m5m.sda6.dump-copied-on-freebsd10.0 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 71.2292 s, 129 MB/s
[root@hoge ~]# dd if=/tank4/backup/m5m.sda6.dump-copied-on-centos6 of=/dev/null bs=1M
8780+1 records in
8780+1 records out
9207209203 bytes (9.2 GB) copied, 72.7268 s, 127 MB/s

1ユーザのパーソナル利用環境での数値ですし、参考までですが、実験したワークロードにおいては、CentOS が良好な結果となりました。

あと2点補足ですが、ZFS のチューニング (ARCサイズ調整等) は行っていないデフォルトでの実験結果です。 また、当該 ZFS 領域には圧縮オプションは指定していません。
プールのプロパティを示します。
[root@hoge ~]# zpool get all tank4
NAME   PROPERTY               VALUE                  SOURCE
tank4  size                   368G                   -
tank4  capacity               79%                    -
tank4  altroot                -                      default
tank4  health                 ONLINE                 -
tank4  guid                   1893700132493715388    default
tank4  version                -                      default
tank4  bootfs                 -                      default
tank4  delegation             on                     default
tank4  autoreplace            off                    default
tank4  cachefile              -                      default
tank4  failmode               wait                   default
tank4  listsnapshots          off                    default
tank4  autoexpand             off                    default
tank4  dedupditto             0                      default
tank4  dedupratio             1.00x                  -
tank4  free                   74.0G                  -
tank4  allocated              294G                   -
tank4  readonly               off                    -
tank4  ashift                 12                     local
tank4  comment                -                      default
tank4  expandsize             0                      -
tank4  freeing                0                      default
tank4  feature@async_destroy  enabled                local
tank4  feature@empty_bpobj    active                 local
tank4  feature@lz4_compress   active                 local
[root@hoge ~]# zfs get all tank4/backup
NAME          PROPERTY              VALUE                  SOURCE
tank4/backup  type                  filesystem             -
tank4/backup  creation              Sat Feb  1  9:43 2014  -
tank4/backup  used                  66.4G                  -
tank4/backup  available             67.2G                  -
tank4/backup  referenced            66.4G                  -
tank4/backup  compressratio         1.00x                  -
tank4/backup  mounted               yes                    -
tank4/backup  quota                 none                   default
tank4/backup  reservation           none                   default
tank4/backup  recordsize            128K                   default
tank4/backup  mountpoint            /tank4/backup          default
tank4/backup  sharenfs              off                    default
tank4/backup  checksum              on                     default
tank4/backup  compression           off                    local
tank4/backup  atime                 off                    inherited from tank4
tank4/backup  devices               on                     default
tank4/backup  exec                  on                     default
tank4/backup  setuid                on                     default
tank4/backup  readonly              off                    default
tank4/backup  zoned                 off                    default
tank4/backup  snapdir               hidden                 default
tank4/backup  aclinherit            restricted             default
tank4/backup  canmount              on                     default
tank4/backup  xattr                 on                     default
tank4/backup  copies                1                      default
tank4/backup  version               4                      -
tank4/backup  utf8only              off                    -
tank4/backup  normalization         none                   -
tank4/backup  casesensitivity       sensitive              -
tank4/backup  vscan                 off                    default
tank4/backup  nbmand                off                    default
tank4/backup  sharesmb              off                    default
tank4/backup  refquota              none                   default
tank4/backup  refreservation        none                   default
tank4/backup  primarycache          all                    default
tank4/backup  secondarycache        all                    default
tank4/backup  usedbysnapshots       0                      -
tank4/backup  usedbydataset         66.4G                  -
tank4/backup  usedbychildren        0                      -
tank4/backup  usedbyrefreservation  0                      -
tank4/backup  logbias               latency                default
tank4/backup  dedup                 off                    default
tank4/backup  mlslabel              none                   default
tank4/backup  sync                  standard               default
tank4/backup  refcompressratio      1.00x                  -
tank4/backup  written               66.4G                  -
tank4/backup  snapdev               hidden                 default

なお、手持ちデータがありませんので、ここ2年ほど ZFS on Linux を使ってみた経験上の話しですが、多数のファイルを含む tar ファイルの展開のような、メタデータ処理が多いワークロードは、ext4 等と比べて苦手なようです。あと、NFS はかなり苦手(ZIL使わない/使えない場合)のようで、NFS export する場合は、ZVOL + ext4 として export すると良い結果が得られると思います。ZVOL でも圧縮機能や snapshot を使えるので有益ですし、オンラインで割り当てサイズ (volsize) 拡張することも可能です。

2014-03-23追記
tar の展開についても比較してみました。展開に使ったアーカイブは、btrfs の実験に使ったものと同じです。
root@hoge:~# uname -a
SunOS hoge 5.11 oi_151a9 i86pc i386 i86pc Solaris
root@hoge:~# zpool import tank4
root@hoge:~# cd /tank4/backup
root@hoge:/tank4/backup# ls -l sda6.tar
-rw-r--r-- 1 root root 10927441920 2013-10-20 22:44 sda6.tar
root@hoge:/tank4/backup# time tar xf sda6.tar

real    4m2.966s
user    0m4.219s
sys     1m8.711s
root@hoge:/tank4/backup# time rm -rf test.restore

real    0m27.575s
user    0m0.495s
sys     0m7.178s
root@hoge:/tank4/backup# cd
root@hoge:~# zpool export tank4
root@hoge:~ # uname -a
FreeBSD hoge 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
root@hoge:~ # zpool import tank4
root@hoge:~ # cd /tank4/backup
backup/  backup2/ backup3/
root@hoge:~ # cd /tank4/backup
root@hoge:/tank4/backup # ls -l sda6.tar
-rw-r--r--+ 1 root  wheel  10927441920 Oct 20 22:44 sda6.tar
root@hoge:/tank4/backup # time tar xf sda6.tar
3.651u 29.506s 5:08.18 10.7%    66+173k 59704+418539io 12pf+0w
root@hoge:/tank4/backup # time rm -rf test.restore
0.336u 12.340s 1:09.05 18.3%    15+165k 26766+0io 0pf+0w
root@hoge:/tank4/backup # cd
root@hoge:~ # zpool export tank4
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# zpool import tank4
[root@hoge ~]# cd /tank4/backup
[root@hoge backup]# ls -l sda6.tar
-rw-r--r-- 1 root root 10927441920 Oct 20 22:44 sda6.tar
[root@hoge backup]# time tar xf sda6.tar

real    3m51.565s
user    0m3.033s
sys     0m46.419s
[root@hoge backup]# time rm -rf test.restore

real    2m1.249s
user    0m0.471s
sys     0m16.205s
[root@hoge backup]# cd
[root@hoge ~]# zpool export tank4
この実験では、CentOS は、削除(rm)が苦手という結果になりました。現在の Linux 実装は、vmalloc に依存しており(meminfo を見ればわかります)、そこら辺に性能が出ない原因があるのではと思いますが、将来は他の Linux の fs と同様にページキャッシュを使う構造になるはず(既に試みが行われている)であり、まだ、性能向上の余地が残っているということでもあろうと思います。

2014-03-25追記
ものはついでに、LZ4 圧縮を有効にした場合についても、やってみました。
root@hoge:~# uname -a
SunOS hoge 5.11 oi_151a9 i86pc i386 i86pc Solaris
root@hoge:~# zpool import tank4
root@hoge:~# zpool list tank4
NAME    SIZE  ALLOC   FREE  EXPANDSZ    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   271G  96.7G         -    73%  1.00x  ONLINE  -
root@hoge:~# zfs list tank4/backup
NAME           USED  AVAIL  REFER  MOUNTPOINT
tank4/backup  72.8G  89.9G  72.8G  /tank4/backup
root@hoge:~# zfs get compression tank4/backup
NAME          PROPERTY     VALUE     SOURCE
tank4/backup  compression  off       local
root@hoge:~# zfs set compression=lz4 tank4/backup
root@hoge:~# zfs get compression tank4/backup
NAME          PROPERTY     VALUE     SOURCE
tank4/backup  compression  lz4       local
root@hoge:~# cd /tank4/backup
root@hoge:/tank4/backup# ls -l sda6.tar 
-rw-r--r-- 1 root root 10927441920 2013-10-20 22:44 sda6.tar
root@hoge:/tank4/backup# time tar xf sda6.tar 

real 2m40.653s
user 0m4.100s
sys 0m50.868s
root@hoge:/tank4/backup# time rm -rf test.restore

real 0m15.588s
user 0m0.425s
sys 0m6.385s
root@hoge:/tank4/backup# cd
root@hoge:~# zpool export tank4
root@hoge:~ # uname -a
FreeBSD hoge 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
root@hoge:~ # zpool import tank4
root@hoge:~ # zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   271G  96.7G    73%  1.00x  ONLINE  -
root@hoge:~ # zfs list tank4/backup
NAME           USED  AVAIL  REFER  MOUNTPOINT
tank4/backup  72.8G  89.9G  72.8G  /tank4/backup
root@hoge:~ # zfs get compression tank4/backup
NAME          PROPERTY     VALUE     SOURCE
tank4/backup  compression  lz4       local
root@hoge:~ # cd /tank4/backup
root@hoge:/tank4/backup # ls -l sda6.tar 
-rw-r--r--+ 1 root  wheel  10927441920 Oct 20 22:44 sda6.tar
root@hoge:/tank4/backup # time tar xf sda6.tar 
3.772u 29.051s 3:11.58 17.1% 66+173k 56955+418539io 12pf+0w
root@hoge:/tank4/backup # time rm -rf test.restore
0.446u 11.615s 0:42.61 28.2% 15+171k 17198+0io 0pf+0w
root@hoge:/tank4/backup # cd
root@hoge:~ # zpool export tank4
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# zpool import tank4
[root@hoge ~]# zpool list tank4
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank4   368G   271G  96.7G    73%  1.00x  ONLINE  -
[root@hoge ~]# zfs list tank4/backup
NAME           USED  AVAIL  REFER  MOUNTPOINT
tank4/backup  72.8G  89.9G  72.8G  /tank4/backup
[root@hoge ~]# zfs get compression tank4/backup
NAME          PROPERTY     VALUE     SOURCE
tank4/backup  compression  lz4       local
[root@hoge ~]# cd /tank4/backup
[root@hoge backup]# ls -l sda6.tar 
-rw-r--r-- 1 root root 10927441920 Oct 20 22:44 sda6.tar
[root@hoge backup]# time tar xf sda6.tar 

real 2m15.379s
user 0m3.018s
sys 0m44.704s
[root@hoge backup]# time rm -rf test.restore

real 1m18.267s
user 0m0.318s
sys 0m13.814s
[root@hoge backup]# cd
[root@hoge ~]# zpool export tank4
すごい効果です。CentOS の tar 展開の処理時間は、Btrfs の compress-force=lzo の実験結果と同等です。それにしても、OpenIndiana の rm は抜群に速い(FreeBSDの2倍以上)ですね。

2014-04-29追記
RHEL7.0 RC と、最新の ZFS(未だに 0.6.3 が出ないので GitHub から落とした)を試してみました。こちら

2014年3月9日日曜日

CentOS 6 の root ファイルシステムに ZFS を使ってみた

ZFS on Linux 0.6.2 には zfs-dracut というパッケージが用意されており、root ファイルシステムに ZFS を利用するための仕組みが入っています。しかしながら、CentOS 6 の dracut は、バージョンが古いため、そのままでは動きませんでした。
dracut のデバッグが厄介だったのですが、どうにか動きましたので、まとめておきたいと思います。
2016-07-02追記、CentOS 7 の GRUB2 から ZFS 上の CentOS 6 を起動する方法も書きました。こちらのほうが運用し易いかと思います。

まず、前提ですが、カーネルと initramfs イメージは、GRUB が扱えるファイルシステム上に置く必要があるので、/boot だけは ext4 等にする必要があります。また、直接 ZFS 上にインストールはできないので、ext4 にインストール後に、引っ越すという手順をとる必要があります。また、将来 ZFS のバージョンアップを行う際、起動できなくならないように注意する必要がある(引越し前の ext4 の root イメージを保持しておく等の対策が必要)かと思います。また、たしか ZOL は SELinux には対応していなかったと思いますので、留意する必要があるかと思います。

以下、手順です。

(1) zfs-dracut に含まれる dracut 用のスクリプトをコピーする
# rpm -ql zfs-dracut
/lib/dracut/modules.d/90zfs
/lib/dracut/modules.d/90zfs/module-setup.sh
/lib/dracut/modules.d/90zfs/mount-zfs.sh
/lib/dracut/modules.d/90zfs/parse-zfs.sh  ※この3つをコピー
/usr/share/doc/zfs-dracut-0.6.2
/usr/share/doc/zfs-dracut-0.6.2/README.dracut.markdown
# cp -r /lib/dracut/modules.d/90zfs /usr/share/dracut/modules.d

(2) スクリプトに修正を加える
まず、関数モジュール化されたスクリプト(中を見ると関数定義だけになっており、最近の Fedora の dracut 向けの作法になってます)をコピーします。
# cd /usr/share/dracut/modules.d/90zfs
# cp module-setup.sh check
# cp module-setup.sh install
コピーしたスクリプトをちょっと加工します。差分は次の通りです。
# diff -u module-setup.sh check 
--- module-setup.sh 2013-08-23 06:39:05.000000000 +0900
+++ check 2014-02-22 21:29:28.000000000 +0900
@@ -54,3 +54,5 @@
  inst_simple "$TMP" /etc/hostid
  rm "$TMP"
 }
+
+check
# diff -u module-setup.sh install 
--- module-setup.sh 2013-08-23 06:39:05.000000000 +0900
+++ install 2014-02-22 21:30:14.000000000 +0900
@@ -31,6 +31,7 @@
  inst_rules /lib/udev/rules.d/90-zfs.rules
  inst_rules /lib/udev/rules.d/69-vdev.rules
  inst_rules /lib/udev/rules.d/60-zvol.rules
+ dracut_install /bin/awk
  dracut_install /sbin/zfs
  dracut_install /sbin/zpool
  dracut_install /lib/udev/vdev_id
@@ -54,3 +55,5 @@
  inst_simple "$TMP" /etc/hostid
  rm "$TMP"
 }
+
+install
さらに、mount-zfs.sh と parse-zfs.sh に修正を加えます。
# diff -u /lib/dracut/modules.d/90zfs /usr/share/dracut/modules.d/90zfs
Only in /usr/share/dracut/modules.d/90zfs: check
Only in /usr/share/dracut/modules.d/90zfs: install
diff -u /lib/dracut/modules.d/90zfs/mount-zfs.sh /usr/share/dracut/modules.d/90zfs/mount-zfs.sh
--- /lib/dracut/modules.d/90zfs/mount-zfs.sh 2013-08-23 06:39:05.000000000 +0900
+++ /usr/share/dracut/modules.d/90zfs/mount-zfs.sh 2014-03-08 20:43:21.086727408 +0900
@@ -2,6 +2,22 @@
 
 . /lib/dracut-lib.sh
 
+# copied from Fedora19's /usr/lib/dracut/modules.d/99base/dracut-lib.sh
+getargbool() {
+    local _b
+    unset _b
+    local _default
+    _default=$1; shift
+    _b=$(getarg "$@")
+    [ $? -ne 0 -a -z "$_b" ] && _b=$_default
+    if [ -n "$_b" ]; then
+        [ $_b = "0" ] && return 1
+        [ $_b = "no" ] && return 1
+        [ $_b = "off" ] && return 1
+    fi
+    return 0
+}
+
 ZPOOL_FORCE=""
 
 if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
diff -u /lib/dracut/modules.d/90zfs/parse-zfs.sh /usr/share/dracut/modules.d/90zfs/parse-zfs.sh
--- /lib/dracut/modules.d/90zfs/parse-zfs.sh 2013-08-23 06:39:05.000000000 +0900
+++ /usr/share/dracut/modules.d/90zfs/parse-zfs.sh 2014-02-22 21:30:39.000000000 +0900
@@ -54,5 +54,6 @@
 # modules to settle before mounting.
 if [ "${wait_for_zfs}" = "1" ]; then
  ln -s /dev/null /dev/root 2>/dev/null
- echo '[ -e /dev/zfs ]' > $hookdir/initqueue/finished/zfs.sh
+# echo '[ -e /dev/zfs ]' > $hookdir/initqueue/finished/zfs.sh
+ echo '[ -e /dev/zfs ]' > /initqueue-finished/zfs.sh
 fi

(3) 引越し先の ZFS root ファイルシステムを用意する
FreeBSD や OpenIndiana を眺めてみて、rpool/ROOT/cent6 のようなネーミングが良いだろうかとも思いましたが、やっぱり長すぎるかなとも思い、rpool/ROOT のようにしました。また、mountpoint プロパティを legacy 設定にする必要があります。
# zfs set mountpoint=legacy tank4/ROOT
# zfs get all -s local tank4/ROOT
NAME        PROPERTY              VALUE                  SOURCE
tank4/ROOT  mountpoint            legacy                 local
今回は実験ということで、既存のプール tank4 から切り出しました。もっと細かく、/var や /home を別に切り出してもいいのでしょうが、わたしの用途では、そこまでする必要を感じませんので、ROOT のみです。

(4) ルート(/)イメージのコピー
マウントしたままコピーは気が引けるので、LiveDVD 等で起動して dump コマンドを用いて、ext4 上のルート(/)イメージをバックアップします。
# dump -y -0uf /mnt_backup_disk/sdXX.dump /dev/sdXX
ext4 から起動して、ZFS 上へ展開します。
# mkdir /mnt_tank4_ROOT
# mount -t zfs tank4/ROOT /mnt_tank4_ROOT
# cd /mnt_tank4_ROOT
# restore -rf /mnt_backup_disk/sdXX.dump

(5) grub.conf に ZFS から起動するためのエントリを作成する
/boot/grub.conf に次のようにエントリーを追加します。initrd は、ext4 root 用のものとは別名(.zfsを付加)にしておきます。
title CentOS on ZFS (2.6.32-431.5.1.el6.x86_64)
        root (hd0,5)
        kernel /boot/vmlinuz-2.6.32-431.5.1.el6.x86_64 ro root=ZFS=tank4/ROOT rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M  KEYBOARDTYPE=pc KEYTABLE=jp106 rd_NO_LVM rd_NO_DM elevator=deadline
        initrd /boot/initramfs-2.6.32-431.5.1.el6.x86_64.img.zfs

(6) fstab を書き換える
ZFS root 上の fstab の / エントリーを次のように書き換えます。
#UUID=xxxxxxxx-yyyy-zzzz-uuuu-vvvvvvvvvvvv /  ext4  defaults  1 1
tank4/ROOT                                 /  zfs   defaults  1 0

(7) ZFS root 用の initramfs を作成する
# mount -t zfs tank4/ROOT /mnt_tank4_ROOT
# mount -t devtmpfs devtmpfs /mnt_tank4_ROOT/dev
# mount -t devpts devpts /mnt_tank4_ROOT/dev/pts
# mount -t sysfs sysfs /mnt_tank4_ROOT/sys
# mount -t proc proc /mnt_tank4_ROOT/proc
# mount --bind /boot /mnt_tank4_ROOT/boot  ※ここ注意、ZFS root 上の /boot に作っておいてコピーでもOKですが
# chroot /mnt_tank4_ROOT /bin/bash
# dracut -f /boot/initramfs-2.6.32-431.5.1.el6.x86_64.img.zfs 2.6.32-431.5.1.el6.x86_64

以上です。

わたしの実験用マシン(ThinkPad T510)の様子を、参考に示します。
[root@hoge ~]# uname -a
Linux hoge 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@hoge ~]# cat /proc/cmdline 
ro root=ZFS=tank4/ROOT rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M  KEYBOARDTYPE=pc KEYTABLE=jp106 rd_NO_LVM rd_NO_DM elevator=deadline
[root@hoge ~]# df
Filesystem     1K-blocks      Used Available Use% Mounted on
tank4/ROOT     121070464  15237632 105832832  13% /
tmpfs            3959608        80   3959528   1% /dev/shm
tank4          119538944  13706112 105832832  12% /tank4
tank4/backup   148460288  42627456 105832832  29% /tank4/backup
tank4/backup2  108885632   3052800 105832832   3% /tank4/backup2
tank4/backup3  291054080 185221248 105832832  64% /tank4/backup3
[root@hoge ~]# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
tank4           261G   101G  13.1G  /tank4
tank4/ROOT     14.5G   101G  14.5G  legacy
tank4/backup   40.7G   101G  40.7G  /tank4/backup
tank4/backup2  2.91G   101G  2.91G  /tank4/backup2
tank4/backup3   177G   101G   177G  /tank4/backup3
tank4/swap     1.03G   102G    80K  -
tank4/test      136K   101G   136K  legacy
tank4/zvol32   12.5G   101G  12.5G  -
[root@hoge ~]# zpool status
  pool: tank4
 state: ONLINE
  scan: scrub repaired 0 in 1h21m with 0 errors on Sun Mar  2 18:24:46 2014
config:

 NAME                                                        STATE     READ WRITE CKSUM
 tank4                                                       ONLINE       0     0     0
   mirror-0                                                  ONLINE       0     0     0
     ata-HITACHI_HTS725050A9A364_xxxxxxxxxxxxxxxxxxxx-part1  ONLINE       0     0     0
     ata-HGST_HTS721010A9E630_yyyyyyyyyyyyyy-part1           ONLINE       0     0     0

errors: No known data errors
[root@hoge ~]# zfs get all tank4/ROOT
NAME        PROPERTY              VALUE                  SOURCE
tank4/ROOT  type                  filesystem             -
tank4/ROOT  creation              Sat Feb 22 21:58 2014  -
tank4/ROOT  used                  14.5G                  -
tank4/ROOT  available             101G                   -
tank4/ROOT  referenced            14.5G                  -
tank4/ROOT  compressratio         1.00x                  -
tank4/ROOT  mounted               yes                    -
tank4/ROOT  quota                 none                   default
tank4/ROOT  reservation           none                   default
tank4/ROOT  recordsize            128K                   default
tank4/ROOT  mountpoint            legacy                 local
tank4/ROOT  sharenfs              off                    default
tank4/ROOT  checksum              on                     default
tank4/ROOT  compression           off                    default
tank4/ROOT  atime                 off                    inherited from tank4
tank4/ROOT  devices               on                     default
tank4/ROOT  exec                  on                     default
tank4/ROOT  setuid                on                     default
tank4/ROOT  readonly              off                    default
tank4/ROOT  zoned                 off                    default
tank4/ROOT  snapdir               hidden                 default
tank4/ROOT  aclinherit            restricted             default
tank4/ROOT  canmount              on                     default
tank4/ROOT  xattr                 on                     default
tank4/ROOT  copies                1                      default
tank4/ROOT  version               5                      -
tank4/ROOT  utf8only              off                    -
tank4/ROOT  normalization         none                   -
tank4/ROOT  casesensitivity       sensitive              -
tank4/ROOT  vscan                 off                    default
tank4/ROOT  nbmand                off                    default
tank4/ROOT  sharesmb              off                    default
tank4/ROOT  refquota              none                   default
tank4/ROOT  refreservation        none                   default
tank4/ROOT  primarycache          all                    default
tank4/ROOT  secondarycache        all                    default
tank4/ROOT  usedbysnapshots       0                      -
tank4/ROOT  usedbydataset         14.5G                  -
tank4/ROOT  usedbychildren        0                      -
tank4/ROOT  usedbyrefreservation  0                      -
tank4/ROOT  logbias               latency                default
tank4/ROOT  dedup                 off                    default
tank4/ROOT  mlslabel              none                   default
tank4/ROOT  sync                  standard               default
tank4/ROOT  refcompressratio      1.00x                  -
tank4/ROOT  written               14.5G                  -
tank4/ROOT  snapdev               hidden                 default
ここまで、実験的に約2週間ほど動かしましたが、安定しています。scrub をかけるとちょっと重いですが、実サーバで使えないこともないかなと思いました。ただ、ZFS 自体のアップデートだけが難点です。0.6.3 が出るのも間近みたいですし、そのあとも着々と開発が計画されているようです。
人気ブログランキングへ にほんブログ村 IT技術ブログへ