Skip to content

ZFSの使い方

2016/7/3

ファイルシステム、ZFSの機能に重複排除機能がある。
バックアップ用のファイルシステムについて、是非とも重複排除機能を使いたいと考えていた。
ZFSの導入から使い方まで。

なお、環境はCentOS 7.1を用いている。

ZFSの導入

リポジトリ登録

# rpm -Uvh http://archive.zfsonlinux.org/epel/zfs-release.el7.noarch.rpm

zfsをインストール

# yum install zfs kernel-devel

上記コマンドにあるように、zfs以外にkernel-develも入れる。
インストール後、ZFSのモジュールをロードする必要がある。
そのため、動作確認も含めて一度OSをリブートすると良い。
ちなみに、モジュールがロードされていないと以下のようなメッセージが出力される。

# zpool list

The ZFS modules are not loaded.
Try running '/sbin/modprobe zfs' as root to load them.

モジュールがロードされていればエラーメッセージが消える。

# zpool list

no pools available

プールをまだ作っていないのでプールが存在しないメッセージが表示される。

ストレージの設定

ラベルの確認

今回の環境では3TBのHDDを用意した。
2TB以上のHDDはGPTにする必要がある。
GPTは"fdisk"では扱えないため、CentOS標準で入っている"parted"を用いる。

# parted -l

未フォーマットの場合、以下のメッセージが表示される

エラー: /dev/sdb: ディスクラベルが認識できません。
モデル: ATA WDC WD30EZRZ-00Z (scsi)                                       
ディスク /dev/sdb: 3001GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: unknown
ディスクフラグ: 

GTPの設定

以下の通り、対話形式でGPTの設定を行う。

# parted /dev/sdb

GNU Parted 3.1
/dev/sdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。

(parted) mklabel gpt
(parted) quit

通知: 必要であれば /etc/fstab を更新するのを忘れないようにしてください。

設定後、確認するとGPTになっていることがわかる。

# parted -l

モデル: ATA WDC WD30EZRZ-00Z (scsi)
ディスク /dev/sdb: 3001GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt
ディスクフラグ: 

zfsのストレージプール作成

zfsはストレージプールを作成し、保存領域を管理する。
プールを作成するには以下の通りコマンドを実行する。

# zpool create [-m マウント先] [プール名] [RAID設定] [デバイス1] [デバイス2] ...

なお、マウント先を指定しない場合はプール名のディレクトリが作成され、ルート直下にマウントされる。

# zpool create zfs_volume /dev/sdb

RAIDはraid0(デフォルト),raidz,raidz2,mirror(raid1)などなどいろいろある。
ZFSはファイルシステムレベルでraidに対応している。
(LVMやmdなどもRAIDには対応しているがZFSのほうが使いやすい印象)

プールを確認してみる。

# zpool list
NAME         SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
zfs_volume  2.72T   284K  2.72T         -     0%     0%  1.00x  ONLINE  -

# zpool status
  pool: zfs_volume
 state: ONLINE
  scan: none requested
config:
    NAME        STATE     READ WRITE CKSUM
    zfs_volume  ONLINE       0     0     0
      sdb       ONLINE       0     0     0

errors: No known data errors

# df -h
zfs_volume                        2.7T     0  2.7T    0% /zfs_volume

※ちなみに、プール名は自由だがtankにするのが一般的らしい。

backup用領域を作る

ZFSンのボリュームをバックアップ用途で追加たかったため、zfs_vlumeのプールの下に、backupという領域を作る。
なお、新たに領域を作らなくても/zfs_volumeに書き込むことはできるが、後に出てくるスナップショットを作ったりするときのために用途に応じて分けておいたほうが良い。

# zfs create zfs_volume/backup

# zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
zfs_volume          376K  2.63T   100K  /zfs_volume
zfs_volume/backup    96K  2.63T    96K  /zfs_volume/backup

# df -h
zfs_volume                        2.7T     0  2.7T    0% /zfs_volume
zfs_volume/backup                 2.7T     0  2.7T    0% /zfs_volume/backup

ZFSの色々な機能

重複排除設定

超強力な重複排除機能。
特にバックアップ等の用途の場合、重複するファイルが多くなるため、実際の容量と比べ、10分の1程度まで容量が少なくなることもある。
(まだZFSで試した結果ではないが、他の重複排除製品での経験から)
ファイル単位ではなく、ブロック単位で重複排除を行うからすごい。
書き込めば勝手に重複排除してくれるため、使うときにあまり気にかける必要もない。

設定の確認

# zfs get dedup zfs_volume
NAME        PROPERTY  VALUE          SOURCE
zfs_volume  dedup     off            default

VALUE=off なので重複排除機能は設定されていない。

設定する。

# zfs set dedup=on zfs_volume

# zfs get dedup 
NAME               PROPERTY  VALUE          SOURCE
zfs_volume         dedup     on             local
zfs_volume/backup  dedup     on             inherited from zfs_volume

VALUE=on なので重複排除機能は設定された。

圧縮機能の有効化

ZFSは他に圧縮機能も搭載されている。
ファイルが書き込まれるたびに自動でファイルが圧縮される。
DiskI/Oが重要なシステムでは使うべきではないが、
ファイルサーバやバックアップ等の用途には良い機能。

設定の確認

# zfs get compression
NAME               PROPERTY     VALUE     SOURCE
zfs_volume         compression  off       local
zfs_volume/backup  compression  off       inherited from zfs_volume

VALUE=off なので圧縮機能は設定されていない。

圧縮方式にgzipを指定して有効化

# zfs set compression=gzip zfs_volume

gzipの圧縮レベルを指定できる。 gzipの箇所について、gzip-1〜gzip-9と入力し指定が可能。
何も指定しないと、gzip-6が設定されるらしい。

# zfs get compression
NAME               PROPERTY     VALUE     SOURCE
zfs_volume         compression  gzip      local
zfs_volume/backup  compression  gzip      inherited from zfs_volume

書き込む際に圧縮処理が走るので圧縮レベルに応じてCPU負荷が上がる。
I/O速度も下がる。
圧縮方式はgzipの他にはlzjbというものも指定できる。
(試していないが、デフォルトだとlzjbらしい)

スナップショット

ZFSはスナップショット機能を持っている。
スナップショットを作成するには以下の通りコマンドを入力する。

zfs snapshot [領域名]@[スナップショット名]

# zfs snapshot zfs_volume/backup@ss1
# zfs list -t all
NAME                    USED  AVAIL  REFER  MOUNTPOINT
zfs_volume              448K  2.63T   100K  /zfs_volume
zfs_volume/backup       120K  2.63T   120K  /zfs_volume/backup
zfs_volume/backup@ss1      0      -   120K  -

スナップショットの削除は以下の通り。

# zfs destroy zfs_volume/backup@ss1

クローンの作成

作成したスナップショットに対して、クローンを作成することができる。
(スナップショットからでないとクローンができない)
クローンを作成するには以下の通り入力する。

zfs clone [snapshot領域名] [クローン名]

# zfs clone zfs_volume/backup@ss1 zfs_volume/backup_clone
# zfs list -t all
NAME                      USED  AVAIL  REFER  MOUNTPOINT
zfs_volume                540K  2.63T   104K  /zfs_volume
zfs_volume/backup         120K  2.63T   120K  /zfs_volume/backup
zfs_volume/backup@ss1        0      -   120K  -
zfs_volume/backup_clone    64K  2.63T   112K  /zfs_volume/backup_clone

ちなみに、cloneがあるとcloneの元が消せないので注意。
以下の通りメッセージが出力される。

# zfs destroy zfs_volume/backup@ss1
cannot destroy 'zfs_volume/backup@ss1': snapshot has dependent clones
use '-R' to destroy the following datasets:
zfs_volume/backup_clone

-Rオプションでclone元とclone同時に消せる

# zfs destroy -R zfs_volume/backup@ss1

スナップショットのコピー

スナップショットはコピーすることができる。
クローンとの違いは、完全に別の領域としてコピーするところ。
別の領域となるため、コピー元を削除することが可能となる。
コピーは以下の通り。

zfs send [スナップショットした領域名] | zfs receive [コピー名]

クローンと同じく、スナップショットじゃないとコピーできない。
スナップショットではないものをコピーしよとすると以下の通りメッセージが表示された。

# zfs send zfs_volume/backup | zfs receive zfs_volume/backup_copy

warning: cannot send 'zfs_volume/backup': target is busy; if a filesystem, it must not be mounted

(メッセージ的にアンマウントすればコピーできる?)

# zfs send zfs_volume/backup@ss1 | zfs receive zfs_volume/backup_copy

# zfs list -t all
NAME                         USED  AVAIL  REFER  MOUNTPOINT
zfs_volume                   676K  2.63T   108K  /zfs_volume
zfs_volume/backup            120K  2.63T   120K  /zfs_volume/backup
zfs_volume/backup@ss1           0      -   120K  -
zfs_volume/backup_copy       184K  2.63T   100K  /zfs_volume/backup_copy
zfs_volume/backup_copy@ss1    84K      -   120K  -

zfs_volume/backup_copy@ss1は自動で作成されていた。
コピーしてしまえば元のスナップショットも消せる

# zfs destroy zfs_volume/backup@ss1

マウントポイントの変更

マウントポイントはあとからでも変えることができる。

マウントポイントの確認

# zfs get mountpoint zfs_volume/test
NAME             PROPERTY    VALUE             SOURCE
zfs_volume/test  mountpoint  /zfs_volume/test  default

設定するには以下の通り。

zfs set mountpoint=[マウント先] [対象の領域名]

# zfs set mountpoint=/mnt/test zfs_volume/test
# df -h
ファイルシステム                    サイズ  使用  残り 使用% マウント位置
zfs_volume/test                   2.7T  128K  2.7T    1% /mnt/test

# zfs get mountpoint zfs_volume/test
NAME             PROPERTY    VALUE       SOURCE
zfs_volume/test  mountpoint  /mnt/test   local

なお、mountpoint プロパティをlegacyに設定すると、mountコマンドやfstabで管理できる

# zfs set mountpoint=legacy zfs_volume/test

# zfs get mountpoint zfs_volume/test
NAME             PROPERTY    VALUE       SOURCE
zfs_volume/test  mountpoint  legacy      local

mountコマンドでマウントする。

# mount -t zfs zfs_volume/test /mnt/test
# df -h
ファイルシステム                    サイズ  使用  残り 使用% マウント位置
zfs_volume/test                   2.7T  128K  2.7T    1% /mnt/test

※なお、fstabを使う場合、zfsはfsckができないため、fsckのオプションに注意(0を指定すること)。

ZFSは簡単に扱えるので、一般家庭のファイルサーバのファイルシステムでもZFSを利用すると良さそう。
ちなみに今までライセンスの関係でLinuxには標準でZFSが搭載されていないのだが、Ubuntu16.04から標準で入っているらしい。