FedoraでZFSを使う

(更新日: 2018/02/06)

Fedora(Linux)でボリューム管理、スナップショット、圧縮、RAID5以上の性能と可能性を持つファイルシステムで”安定しているファイルシステム”となるとZFSしかありません。1

機能的にはBtrfsも同等の機能を持っています。しかし、少なくともこのブログを書いている時点では、RAID56はカーネルがクラッシュした場合などにファイルシステムが壊れてしまう問題があります。2017年8月に修正パッチが提案されていますが、12月現在でも運用環境では使用しないように、と注意書きがあります。

ZFS, Btrfsは両方ともデータの整合性のチェックが可能です。一般にログファイルシステムと呼ばれているファイルシステム(NTFS, XFS2, Ext4など)はディレクトリ情報などのメタデータの整合性をログで維持しています。ZFS、Btrfsはメタデータの整合性に加え、データ自体の整合性もハッシュでチェックしています。冗長性を持たせていない場合でも、HDDのセクタ不良でどのファイルが壊れたのか確実に判ります。

HDDは普通一気に使えない状態になりません。RAID1で冗長性を持たせていても、どちらかのHDDのセクタ不良の場合はどちらのデータが正しいのか?判断できません。ZFSやBtrfsなら、どちらのデータが正しいのか判断できます。

データ整合性の保証はZFS、Btrfsの大きなメリットです。

TL;DR;

ZFSインストール

上記のコマンドでFedoraにZFS on Linuxがインストールされます。ZFSカーネルモジュールのビルドに時間がかかります。

プールとデータセット作成

上記のコマンドでZFS on Linuxがインストールされ、mypoolが作成され、/home/myhomeにZFSのデータセットがマウントされます。プールもZFSで/にプール名でマウントされます。3:

ZFSを利用するハードウェア

システムに必要な最小メモリは2GB程度、推奨は8GB以上です。x86_64, x86両方をサポートしていますが、x86での利用は非推奨です。

FreeBSDベースのNAS OSSのFreeNASのハードウェア要求は一定の参考になります。最低限が8GBのメモリ、推奨が16GBです。ハードウェアRAIDは強く非推奨だとしています。実際、ZFSを利用するならハードウェアRAIDは無用長物どころか有害でさえあります。マザーボードなどのRAID機能は迷わず無効にし、冗長性の確保はZFSで行いましょう。

ZFSのFAQではエラー修正が可能なECCメモリを強く推奨しています。ZFSはかなり堅牢なファイルシステムですが、メモリエラーによる不整合発生は防げません。ファイルの安全性を確実にするにはECCメモリが必要です。ZFSに限ったことではありませんが、不良メモリでファイル/ファイルシステムは壊れます。

ZFSのインストール

Fedoraで利用可能なZFSにはFUSE(ユーザースペースのファイルシステム)を利用したZFSとカーネルモジュールを利用したZFSの2種類が利用可能です。

ZFSのCDDLライセンスはLinuxカーネルのGPLライセンスと互換性がありません。FUSEはカーネルと直接ビルド/リンクしないモジュールをダイナミックにロードするのでライセンス互換性の問題を回避できます。FUSEを利用したzfs-fuseパッケージはFedoraのデフォルトリポジトリにも登録されています。このため、zfs-fuseは容易に利用可能です。しかし、FUSEのZFSは性能的に最適とは言えません。

ここではzfsonlinux.orgのカーネルモジュールを利用する方法を紹介します。

インストール手順

Fedoraにはzfs-fuseパッケージがあるので、依存関係によりzfs-fuseパッケージがインストールされている場合があります。しかも、zfs-fuseに依存するパッケージが多くあり普通に削除できないです。

そこで、zfs-fuseパッケージがインストールされている場合は依存性を無視してアンインストールします。

後はzfsonlinux.orgのFedora用インストール手順に従ってインストールできます。

zfsonlinux.orgのZFSはカーネルモジュールとしてインストールされる為、zfs-fuseに比べ高い性能を持っています。カーネルモジュールなので、カーネルのバージョンアップで使えなくなる場合もあります。/etc/dnf/dnf.confのinstallonly_limitを

などとして古いカーネルが利用しやすいようにすると安全です。

ZFSのプールとデータセットの作成

ZFSはプールとデータセットを利用します。プールはデータセットの入れ物、データセットは大きな入れ物であるプールを小分けにして使いやすくした物、というイメージです。4

ZFSはミラーリング、ストライピング、RAID5のようなストライピングと冗長性を持たせられます。ここではRAIDZを作成します。RAIDZはRAID5と同等と考えても構いません。2台のHDD故障に耐えれるRAIDZ2(RAID6相当)や3台のHDD故障に耐えれるRAIDZ3もサポートしています。5

RAIDZプールの作成

HDDを他のファイルシステム、特にLVMで使っていたHDDを使った場合、LVMが誤認識して起動時に認識しようとすることがあります。既にフォーマット済みのHDDの場合、全てのパーテションのファイルシステムシグニチャーを消しておいた方が良いです。

パーテションがある場合、先にパーテションのシグニチャーを消し、最後にドライブ全体のシグニチャーを消します。

RAIDZのプールは以下のようなコマンドで作成します。

例:mypoolというraidzのZFSプールをID1からID3のデバイスで作成

/mypoolディレクトリが作成され、mypool内全てのzfsデータセットは/mypoolの中に作られます。ashift=12 はブロックサイズを最適化するオプションです。

raidzは3台以上、raidz2は4台以上、raidz3は5台以上のデバイスが必要です。raidzやmirrorなどの指定なして単独のデバイスでプールを作ったり、複数のデバイスを単一のデバイスのように使えるようにもできます。

今のところRAIDZのデバイスにディスクを後から追加して拡張することはできません。オンラインでRAIDZを拡張できるようにするプロジェクトは始まっています。利用できるようになるのはまだ先の話です。

ミラーしたプールの作成

ミラーリングを利用したプールは以下のようなコマンドで作成します。

ミラーには2台以上のHDDが必要です。

単独ドライブのプールは以下のようなコマンドで作成します。

冗長性のないストライピングの作成

複数のドライブを束ねたプールは次のようにします。

作成済みプールの管理

作ったプールはlistやstatusコマンドで参照できます。

何らかの理由、例えばプールのデバイス名が変更されてしまった時など、でプールが初期化できなかった場合、importで利用できるプール名を参照できます。

表示されたプールはimportコマンドでインポートできます。

プールを削除する場合はdestroyを利用します。

パーテションの利用とデバイス名

ここではZFSプールに追加するデバイスはHDDデバイス全体ではなくパーテション、例えば/dev/sdb1など、も指定できます。

ZFSインストールの紹介サイトにはHDDデバイス全体をZFSプールに追加する例が数多く紹介されています。これはOpen ZFSのFAQの解説が理由でしょう。

ディスク全体を使うとパーテションのアライメントを考慮しなくて済みます。この場合、/dev/disk/by-id/のシンボリックリンクを使うと良いです。

異るサイズのディスクを使い、raidzXやmirrorを構成した場合、小さいサイズのディスクサイズまで使えるようになります。後で小さいサイズのディスクを大きくすれば、使っていなかった領域も使えるようになります。

LogファイルのSSDキャッシュ

ZFSはLog File Systemと言われるタイプのファイルシステムで、ディレクトリ情報などのメタデータの整合性をログファイルで維持できるようになっています。このログを高速なSSDなどにキャッシュするし、高速化できます。このログはZIL(ZFS Intent Log)と呼ばれ待ています。

SSDを使っても十分以上に効果があります。速ければ速いほど良いので、バッテリーバックアップ付きのDRAMなどを使うとより効果的です。

Logファイルはあまり大きくなりません。1GB程度のパーテションでも十分ですが、メモリキャッシュ程度の大きさが最大限になるようです。デフォルトではシステムメモリの半分をARC(Adaptive Replacement Cache)と呼ばれるキャッシュに利用します。ARCキャッシュに8GBを割り当て、SSDに4GBのパーテションを作って利用していますが、使い切るようなケースは無いようです。

Logが壊れるとファイルが壊れます。このためLogはミラーするのがベストプラクティスです。複数のSSDドライブを利用できる場合、ミラーすると安全性が増します。

logを削除する場合、removeを使います。

データのSSDキャッシュ

HDDよりSSDの方がより高速です。このキャッシュはL2ARCと呼ばれます。ARC(メモリキャッシュ)があるのでZILよりは効果が低いです。ZILは少ないSSD領域で大きな効果があります。どちらか1つのキャッシュを作るならZILをキャッシュする方が良いです。

十分にキャッシュ領域を確保できるなら、基本的にはLogとCacheを作って使う方が良いです。

cacheを削除する場合、removeを使います。

ZFSデータセットの作成

ZFSデータセットはzfsコマンドで作成します。作ったボリュームは作成時に指定したディレクトリに自動マウントされます。

このコマンドはmypoolにhomeを作成し、起動時に/homeにマウントします。

マウントポイントはデータセット作成後にzfs setでも設定できます。

作成したデータセットはzfs listで参照できます。

何らかの理由で自動マウントされなかったZFSデータセットはzfs mountでマウントできます。

-aオプションは全てのデータセットをマウントします。

圧縮の有効化

プール作成時に-oオプションで圧縮も指定できますが、ここでは後で指定することにします。圧縮方法は複数ありますが、大抵の場合はlz4で十分でしょう。

圧縮率はcompressratioで取得できます。私の環境の場合、vmwareディスクイメージを保存しているZFSの圧縮率は1.6〜1.7程度です。

全てのパラメーターは

で取得できます。これらのパラメータの多くがsetコマンドで値を設定できます。

atimeの調整

ZFSはデフォルトatimeを記録します。xfsやbtrfsのデフォルトであるrealtimeと同等の動作に変更します。

レコードサイズの調整

データベースシステムを利用する場合、ZFSのレコードサイズとデータベースのレコードサイズ(ブロックサイズ)を合わせるとより良い性能を期待できます。PostgreSQL、InnoDBの場合、デフォルトで8KBです。

スナップショット

今日のスナップショットを取得

スナップショット一覧

スナップショット削除

メンテナンス

zpool状態の確認

ZFSプールの一覧

より詳しいZFS情報

インポート可能なプールの確認(認識&マウントできていないプールの確認)

整合性のチェック ー ZFSプールの整合性チェックはオンラインで可能

scrubの進捗

ZFSデータセットの一覧

ZFSデータセットのチェックサム状態 – データ整合性が必要ない場合、チェックサムを無効にすると少し性能が向上する

ZFS ARC統計情報

エラーが起きたディスクのエラー修正

エラーが起きたディスクの交換

 

メモリ管理

ZFSはデフォルトで搭載メモリの半分をARC用に使用します。ファイルサーバーでないマシンのメモリを半分ディスクキャッシュに利用するのは多すぎでしょう。/etc/modprobe.d/zfs.confを作成し、8GBをARCに使う設定をしました。

ZFSを使うとスワップをほとんど行わなくなります。どうしても必要な時にだけスワップします。恐らくARCがスワップされることを防ぐ為だと思われます。もう少しスワップした方が効率的では?と思えるほどスワップしません。気休めですが/etc/sysctl.confにvm.swappinessを設定しています。

最新のカーネルでは問題ないかも知れませんが、vm.nr_hugepages=512を書いておくと、全くスワップが使われませんでした。メモリが逼迫するとOOM Killerが動作してシステムが動作しなくなりました。特に必要のないvm設定は行わない方が安全かも知れません。

カーネルモジュールとDKMS

zfsonlinux.orgのZFSはカーネルモジュールです。カーネルがバージョンアップするとソースコードからZFS用のモジュール(zfs.koとspl.ko)をコンパイルしてインストールしなければなりません。

DKMSはZFSモジュールのようにソースコードで配布されるモジュールを自動コンパイル、自動インストールできるようにする仕組みです。正常に動作している場合は問題ありませんが、不具合などで手動でビルド/インストールしなければならない場合もあります。

DKMS状態の確認

現在のカーネルのzfs.koとspl.koのビルド/インストール

カーネルをバージョンアップする際にDKMSが動作し、モジュールをビルド&インストールします。ZFSインストール前よりカーネルインストールの時間がかなり多く必要になります。気長に待ちましょう。

ZFSのバージョンが上がった場合に、古いカーネルでも最新のZFSモジュールを使うにはdkmsコマンドを使った手動ビルトとインストールが必要になります。

稀にdepmodが終わらない場合もあるようです。仕方無くリブートした場合などは、リブート後に再度実行すればOKです。

その後、modprobeを実行するとZFSが利用できるようになります。

ZFS関連モジュールがロードされていればOKです。

Fedoraリリースのバージョンアップ

ZFSを利用している場合、新しいFedoraリリースが公開されても直ぐにバージョンアップするのは良くないです。zfsonlinux.orgやgithubのリポジトリなどを見て、新しいリリースに対応しているか確認してからバージョンアップしましょう。

ZFSはLinux Kernelとは独立したプロジェクトなので不安に感じる方もいると思います。ZFSを開発しているのはLLNLという米国政府の研究機関です。Fedoraは公式なサポート対象OSになっています。Fedora 27は2017年11月半ばにリリースされ、Fedora 27対応のZFSは12月半ばにリリースされました。

既知の問題

GitHubのIssueが参考になります。単なる問い合わせ/質問に近いモノも多いです。もし質問する場合はメーリングリストを利用しましょう。リストのアーカイブも公開されているので、アーカイブを検索するとよいです。

環境 – Fedora 27, Kernel 4.14.8-300.fc27.x86_64, ZFS zfs-0.7.5-1.fc27.x86_64

  • zpool status が統計情報を更新しない。zfs-fuseでは更新されるが、zfsonlinux.orgのパッケージだと更新されない。scrubの状態は更新される。

参考

 


  1. LVM + XFS + mdraidでそれなりのモノは作れます。しかし、XFSに”データ領域整合性保証がない”、mdraidに2つHDDが異る値を返してきた時に”どちらが正しい情報なのか判別する仕組みがない”です。これは信頼性/可用性を大きく損う原因になっています。 
  2. ArchLinuxのXFS解説に書いてある通り、Note: Unlike Btrfs and ZFS, the CRC32 checksum only applies to the metadata and not actual data. です。データベースなど整合性が重要なシステムでは、データ整合性確認は特に重要です。 
  3. プールのマウントポイントも指定可能です。 
  4. 正しいとは言いきれませんがイメージとしてはこんな感じです。プール自体もZFSのファイルシステムです。0.7.5になってから(?)プールをマウントしたディレクトリの中身がみえませんが、以前のバージョンだとデフォルトの状態でzfs createで作ったファイルシステムを参照できました。 
  5. 16台を越えるデバイスをraidzXで使うことは推奨されていないようです。多数のデバイスを使う場合、raidzXのデバイスを束ねて使うと記述されています。 

Comments

comments