2 ポイント 投稿者 GN⁺ 2023-09-06 | 1件のコメント | WhatsAppで共有
  • FreeNASでのZFS障害をきっかけに、トラブルシューティング、新しいボリューム構成、バックアップ戦略まで整理した入門ガイドで、ZFSを初めて運用する際に必要な構造とコマンドを一連の流れで扱う
  • ZFSはファイルシステムと論理ボリュームマネージャーをあわせて提供し、Sun Microsystemsで始まった後、LinuxやFreeBSDなどでは主にOpenZFSのコードが使われている
  • 基本構造は物理ディスクを束ねるvdev、それを集めたpool、ファイルシステムの役割を持つdataset、ブロックデバイス形式のvolumeに分かれ、RAIDZ-1/2/3はそれぞれ1台、2台、3台のディスク障害に耐えられる
  • 実務で使うコマンドはzpool create/status/list/import/export/destroy/scrubzfs create/mount/list/get/set/snapshot/diff/rollback/send/recv/destroyが中心で、デバイス名変更の問題を避けるにはdevice UUIDの利用が推奨される
  • snapshotは特定時点の状態を軽量に保護し、zfs send/recvで別のpoolやシステムへ複製できるが、snapshotだけでバックアップやDRを代替するのは難しい

ZFSの基本概念

  • ZFSはext4、NTFS、exFATのようなローカルファイルシステムであると同時に、LinuxのLVMのような論理ボリュームマネージャーの役割も果たす
  • Sun Microsystemsが開発し、ZFSのソースコードはOracleによるSun買収前まではオープンソースライセンスで公開されていた
  • すでに公開されたコードが複数のOSへ移植されていたため、その後OpenZFSプロジェクトが立ち上がり、LinuxやFreeBSDなど大半のUnix系システムでこのコードが使われている
  • ZFSに初めて触れる人が構造と運用コマンドを理解できるよう、初心者の視点で整理されている

ZFSの構成要素

  • vdevは1台以上の物理ドライブで構成され、ハードドライブ以外にファイルを含めることもできる
    • mirrorやRAIDZ形式で組み合わせ可能
    • hot spare、L2ARC、ZILのような重要なvdev種別を含め、7種類のvdevタイプがある
  • poolは1つ以上のvdevで構成され、通常はpool内にvolumeやdatasetを作成する
    • zpoolコマンドでpoolを作成する際にvdevもあわせて定義する
    • 複数のvdevタイプを組み合わせてRAIDZレベルを構成できる
  • datasetはZFSにおけるファイルシステムに相当する構成要素
    • ユーザーアクセス、quota、圧縮、snapshotなどを設定できる
  • volumeはdatasetに似ているが、ブロックデバイス表現を提供する
    • datasetの機能の一部のみを提供する
    • ZFS上で別のファイルシステムを動かしたり、iSCSI extentをエクスポートしたりする際に便利

RAIDZの種類

  • Dynamic/Simple Stripe、つまりRAID0はparityなしでデータを分散し、デバイスを1台失うと全データを失う
  • MIRROR、つまりRAID1はディスクをミラーリングし、2〜4台またはそれ以上のディスクとともに使われる
  • RAIDZ-1、つまりRAID5はデータとともにparityを分散し、RAID障害になるまで物理ドライブ1台の損失に耐えられる
    • RAIDZには最低3台のディスクが必要
  • RAIDZ-2、つまりRAID6は最大2台の物理ドライブ損失に耐えられる
    • RAIDZ-2には最低4台のディスクが必要
  • RAIDZ-3は最大3台の物理ドライブ損失に耐える
    • 最低4台のディスクが必要だが、5台未満で使うのは望ましくない

poolの作成と状態確認

  • ZFS poolはzpool create [pool] [devices]形式で作成する
    • 単一ディスクpoolの例: zpool create tank /dev/sdb
    • 3台ディスクstripeの例: zpool create tank /dev/sdb /dev/sdc /dev/sdd
    • 2台ディスクmirrorの例: zpool create tank mirror sdb sdc
    • RAIDZ poolの例: zpool create tank raidz sdb sdc sdd
    • RAIDZ2/3はzpool create [pool name] raidz[1,2,3] [devices]形式で作成できる
  • pool作成時には-mフラグでデフォルトのmount pointを指定できる
    • 例: zpool create tank -m /mnt/tank mirror sdb sdc
  • 例では/dev/sdx形式のデバイス名を使っているが、デバイス名変更による起動問題を避けるにはdevice UUIDの利用が推奨される
  • zpool statusはpool状態を確認する基本コマンド
    • stateはpoolがオンラインかどうかを示す
    • statusはpoolに関する追加情報を表示する
    • actionは必要な次の作業を示す
    • scanはscrubの進行状況または最後のscrub状態を表示する
    • errorsはpoolに問題があるかどうかを示す
  • zpool listはpoolのサイズ、割り当て量、空き容量、fragmentation、capacity、dedup、healthなどの詳細を表示する
  • zpool historyはpool作成以降、構成変更に使われたコマンド履歴を表示する

poolのimport、export、削除、scrub

  • poolは作成後、通常は自動的にimportされmountされるが、トラブルシューティングやシステム再イメージ化の後には手動importが必要になる場合がある
  • zpool importをpool名なしで実行すると、import可能なpool一覧が表示される
    • import可能なpoolがない場合はno pools available to importと表示される
    • pool名を指定するとそのpoolをimportし、importコマンドはpoolのmountも行う
    • zpool import -aはimport可能なすべてのpoolを取り込む
  • zpool import -R /mnt/tank2 tankのように-Rを使うとalternate rootの場所にmountする
    • これはpool自体のmount pathではなく、代替rootフォルダを指す
  • zpool export [pool name]はimportの逆操作で、pool内のmounted filesystemをunmountした後にexportを試みる
    • filesystemのunmountに失敗した場合は-fで強制unmountできる
    • 使用中のZFS volumeがあると、-fを使ってもexportは失敗する
  • zpool destroyはpoolとその配下のdatasetまたはvolumeを削除する
    • すべてのデータとsnapshotまで削除されるため注意が必要
  • ZFS scrubはpool内の全blockを既知のchecksumと照合してデータの整合性を確認する
    • parityのあるvdevでは正常なディスクのデータを使って破損データを修復する
    • システム状態を維持するには、scrubをスケジュールに従って実行する必要がある
    • 開始: zpool scrub [pool]
    • 状態確認: zpool statusscan領域を確認
    • 停止: zpool scrub -s [pool]

datasetの作成とmount

  • zfs createは新しいfilesystemまたはvolumeを作成するコマンドで、ここではvolumeよりdatasetを中心に扱う
  • zfs create tank/dataset1tankの下にdataset1を作成する
    • tank datasetはzpool create時に自動作成される
  • zfs create -pmkdir -pのように、存在しない親datasetもまとめて作成する
    • 親datasetが存在しない場合、通常のzfs createは失敗する
  • zfs mountを引数なしで実行すると、現在mountされているZFS filesystemとmount pointを表示する
    • この出力にはchild datasetは含まれない
  • zfs mount [pool|dataset]は指定したfilesystemをmountする
    • zfs mount -aはすべてのfilesystemをmountする
  • child datasetはparent datasetなしでもmountできる
    • この場合、OS filesystem上に必要なパスが作成される
    • 後からparent datasetをmountしようとすると、作成済みディレクトリのためdirectory is not emptyエラーになることがある
  • zfs unmount [dataset]は指定したdatasetをunmountする

datasetの参照とプロパティ設定

  • zfs list [dataset name]は指定したdatasetの情報を表示する
    • dataset名の代わりにmount pointを引数に指定することもできる
  • zfs listをdataset名なしで実行すると、システム上のすべてのdatasetを再帰的に表示する
  • dataset名を指定する際に-rフラグを使うと、そのdataset配下を再帰的に表示できる
  • ZFS propertyはfilesystem、volume、snapshot、cloneの動作を制御する
    • mount optionに似て見える場合がある
  • zfs get all [dataset]はdatasetのすべてのpropertyを表示する
  • 特定のproperty値はzfs get compression tankのように確認する
  • property設定にはzfs setを使う
    • 例: zfs set compression=lz4 tank
    • 設定後、zfs get compression tankcompressionの値がlz4に変わったことを確認できる

snapshotの仕組みと活用

  • snapshotはfilesystemの特定時点の状態を保存するが、ファイルをコピーするわけではない
  • snapshotは既存データをread-onlyとしてマークし、その後filesystemに新しいデータが追加されても、snapshotが保護する既存data blockには影響しない
  • 例の流れは次のとおり
    • 既存データData Aがあるfilesystemでsnapshot 1を作成する
    • その後Data Bを追加し、snapshot 2を作成する
    • その後Data Cを追加する
    • snapshot 1はData Aを保護し、snapshot 2はData AとData Bを保護する
    • snapshot 1を削除しても、Data Aはsnapshot 2によって引き続き保護される
  • snapshotが使用するデータ量は非常に小さい
    • ファイルをコピーする代わりに、そのsnapshotに属することを示すfilesystem最上位のmetadata blockを記録するため
  • snapshotはソフトウェア開発のテストや、アップグレード前のfailsafe作成に有用
  • snapshotだけをbackupDRソリューションと見なすべきではない

snapshotコマンド

  • snapshot作成はzfs snapshot [pool/dataset@snapshot_name]形式を使う
    • 例: zfs snapshot tank/dataset1@snapshot1
  • snapshot一覧はzfs list -t snapshotで確認する
  • child datasetが複数ある場合は、top-level datasetにsnapshotを作成するか、-rフラグでrecursive snapshotを作成できる
    • 通常snapshotの例: zfs snapshot tank@snapshot-master
    • recursive snapshotの例: zfs snapshot -r tank@recursive
  • zfs diff [older snapshot] [newer snapshot]はsnapshot間の差分を比較する
    • 出力では追加ファイルや変更されたパスを確認できる
  • snapshot復元はzfs rollback [pool/dataset@snapshot_name]で行う
    • rollbackするとsnapshot以降に作成されたファイルは削除される
    • より新しいsnapshotも削除され、この場合は-rオプションの使用を求められることがある

ZFS send/recvと複製

  • ZFS sendはsnapshotをデータstreamとして送れる機能
  • snapshotやdatasetをファイル、別のpool、またはSSH経由で別システムへ複製できる
  • 例ではtankbackupという2つのpoolを使用する
    • tank/Movies datasetに1.50Gのデータがある
    • 転送前にzfs snapshot tank/Movies@$(date '+%Y-%m-%d_%H-%M')でsnapshotを作成する
    • zfs send tank/Movies@2020-11-03_15-29 | zfs recv backup/Moviesでsnapshotをbackup poolへ転送する
  • 転送後、zfs listではbackup/Moviestank/Moviesの両方が見え、zfs list -t snapshotでも両側のsnapshotを確認できる
  • zfs sendはさまざまなオプションやユースケースを掘り下げる価値のある機能で、RAIDZやsnapshotと組み合わせることでfilesystemをより堅牢にできる

datasetとsnapshotの削除

  • dataset削除はzfs destroy [pool/dataset]形式を使う
    • -rフラグも利用できる
  • snapshot削除もzfs destroy [pool/dataset@snapshot_name]を使う
    • snapshot削除にも-rフラグを使える
  • ZFSにはさらに多くの機能があるが、この資料は基本概念とコマンドを学ぶための出発点に近い

参考資料

1件のコメント

 
GN⁺ 2023-09-06
Hacker News のコメント
  • ZFSを始めたばかりだが、思ったより学習曲線が急だ。よくあるユースケースをとても単純にしてくれる、簡単なラッパーがあるといい
    たとえばプール作成では、ashift=12lz4 圧縮、xattr=saacltype=posixaclatime=off のような妥当なデフォルト値をそのまま使い、暗号化は複数のオプションではなくオン/オフだけにしてほしい
    暗号化キーを生成し、起動時にプールを復号する systemd サービスを設定し、キーのバックアップを案内してくれるとよい。zfs list はデータセットがマウントされているか、暗号化されているか、キーがロードされているかを表示すべきだ
    再帰データセットはなくし、{pool}/{dataset} ではなく {pool}:{dataset} でプールとデータセットを明確に区別してほしい。プールやスナップショットの名前も自分で付けずに済むよう、{hostname}-[A-Z]{pool name}_{datetime created} のような規則と数字の短縮名を自動で付けてくれるとよい
    プール作成時にディスク ID を直接入力しなくて済むようにし、/dev/sda/dev/sdb で作った後にドライブの順序を変えても混乱しないよう、ディスクにメタデータを保存してほしい
    進捗状況は常に pv で表示し、週次スクラブと、時間別/日別/週別/月別のスナップショットおよびクリーンアップを自動設定してほしい
    プールのないディスクへ送信する場合は、確認を取ったうえで送信元プールと同じ設定の単一ディスクプールを作成し、zpoolzfs は 1 つのコマンドに統合してほしい
    暗号化データセットの送信時は --raw を自動使用し、送信のデフォルトは --replicate にし、可能なら -I を使ってほしい。スナップショットのファイルシステムを隠しディレクトリに隠すのではなく、スナップショットデータセットを簡単にマウントして探索する方法も必要だ
    • 妥当な提案と非常に強い好みが混ざっている。ashift=12 のデフォルトや {pool}:{dataset} 構文は理解できるが、今から変えるにはもう遅すぎるように見えるし、一部の提案は知らないユースケースを壊しかねない
      ホスト名でプール名を付ける方式は、複数ホストから取り込める SAN プールには合わない
      週次スクラブ、定期スナップショット、定期クリーンアップは OS のスケジューラが担うべき仕事だと思う。zpoolzfs を統合することも可能ではあるだろうが、結局 zfs -pool XXXXzfs -volume XXXX のような形になるはずで、なぜ必要なのか分からない
      再帰データセットは実際に有用な場合がある。一方で、zfs list がマウント有無、暗号化有無、キーのロード有無を表示すべきだという点には全面的に同意する
      ディスク ID を入力させないという部分は曖昧だ。ID、WWN、ラベル、sdX など複数の指定方法はあるが、どのディスクを使うかはいずれにせよ伝える必要がある
      ディスクにメタデータを保存して、順序を変えても見つけられる機能はすでにある。ドライブをいくつか差し替えてからプールをインポートしても見つけてくれる
      一部の提案はデフォルトとして悪くないが、いくつかは自分の利用パターンと必要性の外側を十分に考慮していないように見える。ZFS ははるかに多くのユーザーを対象にしている
    • /dev/sda/dev/sdb でプールを作って ZFS が混乱するというのは、率直に言って ZFS の問題ではなく、今の時代に合った使い方をしていないユーザー側の問題に近い
      Linux にはかなり前から /dev/disk/by-id/ata-$manufactuer-$serial-$whatever のような完全な参照がある。プールを作るときはこうしたパスを使うべきだ
    • 多くの提案はかなり好みに左右されるもので、それ自体が悪いわけではないが、既存の慣例をわざわざ揺さぶっているように見える。たとえば、なぜ {pool}:{dataset} でなければならないのか分からない
      スナップショット名を自分で付けたくないなら、私が作った小さなツール https://github.com/rollcat/zfs-autosnap が合うかもしれない
      zfs-autosnap snap を cron に時間ごとに入れ、zfs-autosnap gc を日ごとに入れれば、保持ポリシーに従ってスナップショット履歴を回してくれる
      簡単な ZFS コマンドラッパーを使うのは難しくないので、私のコードを持っていって自分のツールを作ってもよい
    • 鍛冶屋の徒弟の最後の課題の一つが、本物の鍛冶屋が使うすべての道具、つまり金床、ハンマー、火ばさみなどを自分で作ることだと読んだことがある
      職場でも、その日に想定したデプロイ形態に合わせて ZFS アレイを作るスクリプトをいくつも書いた。その中には、zvol を載せる LUKS 暗号化ボリュームの作成、命名規則の標準化、ashift=12lz4 圧縮のようなデフォルト設定が含まれていた
      これは ZFS ネイティブ暗号化が入るずっと前のことで、今の方式でも問題がないので、ZFS 暗号化をサポートするようにスクリプトを更新してはいない
      今では多くのフラグを覚えていないが、スクリプトがドキュメントの役割を果たしてくれるし、チームの他の人たちは make-zfs-big-mirrormake-big-zfs-undundant-raid0 を実行するだけでよい
      いつか年に 20 回以上システムをプロビジョニングすることになれば、それすらプロビジョニングで自動化できるかもしれない
    • すでに他の人たちが言っているように、非常に 好みの強い提案だ。意見を持つのはよいが、多くの項目は「自分が Linux で慣れているやり方ではない」というものから、実際に問題のある提案まで幅がある
      プール名を付けないというのは筋が通らない。プールをそんなに頻繁に作るわけではないのだから、普通に名前を付ければよい
      スナップショット名を付けたくないなら httmzfs allow を使える。たとえば httm -S .rpool/ROOT/ubuntu_tiebek@snap_2022-12-14-12:31:41_httmSnapFileMount のようなスナップショットを作る
      zfszpool は、それぞれ複数のサブコマンドを持つ優れた Unix コマンドだ。ZFS の設計者たちが、より複雑な単一の管理コマンドを作らなかったのは、とても賢明な判断だったと思う
      スナップショットデータセットを明示的にマウントして探索することも zfs mount で簡単にできる。ただし、安定した仮想インターフェースがすべてのファイルバージョンを検索しやすくしてくれるし、これは btrfs などではずっと難しいという点も信じてほしい。httm も参考になる
      [0]: https://kimono-koans.github.io/opinionated-guide/#dynamic-sn...
  • ZFSにはほかにも便利なものがあります。zpool-attach(8)zpool-replace(8)の違いを知っておくとよく、zfs list -t all -o spaceは容量がどこで使われているかを表示します
    大きな変更やアップグレードの前にOSを保護するには、ZFS Boot Environmentsが最高の機能です。手始めとして https://is.gd/BECTL が役に立つかもしれません
    zpool history poolnameはプール構成と変更履歴をすべて表示します。たとえばzpool createautotrim=onatime=offcompression=zstdrecordsize=1mのような変更が記録されます
    ガイドに抜けている重要な情報もあります。3-wayミラーは3台のディスクのうち2台が故障してもデータが残り、4-wayミラーは4台中3台が故障しても残り、N-wayミラーはN台中N-1台が故障してもデータが保護されます
    データが最重要だがスロットやディスクが多くない場合に有用です

    • N-wayミラーには、ZFSが読み取りを複数ディスクに分散して処理できるという特性もあります。入出力操作数が制限されていた回転式ディスクでは、この点はかなり重要でした
  • 何年も前から、大容量のマルチTB級PostgreSQLデータベースをZFS上で運用しています。ZFSのおかげで、バックアップ、過去のスナップショットに基づくテスト環境の作成、内蔵圧縮によるディスク節約がとても簡単になりました
    興味があれば、経験談を https://lackofimagination.org/2022/04/our-experience-with-po... で読めます

  • ZFSを始めるときに最も役立ったのは、FreeBSDのZFS HandbookとAaron Toponceの記事でした
    [0] https://docs.freebsd.org/en/books/handbook/zfs/
    1 https://pthree.org/2012/04/17/install-zfs-on-debian-gnulinux...

    • FreeBSDのドキュメントが好きです
      転がっていたECC RAM 1GBの古いHP MicroserverにFreeBSDをインストールし、古い500GBハードディスクも5台あったので、FreeBSD Handbookを見ながら5xミラーで構成しました。FreeBSDは初めてでしたが、とてもスムーズでした
  • 最近、主にLAMPサーバーで構成されたインフラを大幅に再構築しながら、効率的なバックアップ複製と暗号化のために、すべてLinux上のZFSベースにすることにしました
    かなり前からバックアップにZFSとrsyncを一緒に使っていたのでそれなりに慣れており、結果的にはうまくいきましたが、きちんとやろうとすると予想よりはるかに時間がかかりました。特にデータベースと複製に関して、Web上には誤った助言が多くありました
    データベースには、少なくともブロックサイズのアラインメントのような基本的なチューニングが必要です。mariadb/InnoDBについては、Let's Encrypt側の資料 https://github.com/letsencrypt/openzfs-nvme-databases が圧倒的によかったです。すべての項目に理由を挙げ、複数の出典を引用しているので価値があります
    Webをさらに探すと、不完全で根拠のない理論を添えた矛盾した助言、逸話、神話が延々と出てきます。結局は自分でテストし、調整する項目を理解する必要がありますし、調整しないと決めるのも問題ありません
    複製については、本当にマニュアルページをおすすめします。ZFSは堅牢な複製ツールを提供していますが、あまりに汎用的なので、Gitの低レベルな配管コマンドのように感じます。SSHで使うことを前提にしていないため自分でつなぎ合わせる必要があり、自動化するには境界条件まで考えなければならないので、最初は怖く感じます
    そのため皆syncoidのようなツールに流れるのですが、syncoid系の複製スクリプトにはひどい点がありました。ZFSのsend --replicationモードを使わず、より柔軟だからという理由でPerlで不完全に再実装しています
    初回テストで新規に復元したところ、すべての暗号化ルートが壊れ、データセットのプロパティがすべて自動同期されないのを見ると、たまったものではありません。組み込みの再帰的な複製オプションだけを使えば、ZFSがこれを処理してくれます
    腰を据えて自分でスクリプトを書けば難しくありません。単純に保ち、syncoidのように不要なものをパイプラインに大量に詰め込まなければよいのです。実際にテストすると、そうしたものが速度を落とすこともあります。進捗はpvで見て、そのまま流せば高速に動作します
    いつか自分の複製スクリプトを公開するかもしれません。基本を扱いつつ、複製をめちゃくちゃに再実装しない良い参考スクリプトはほとんどないと感じています

    • その資料はio_capacityio_capacity_maxのチューニングに触れていますが、MySQLのドキュメントを開いて実際のパラメータの役割を見ると、残念ながらそれほど有用ではありません
      これらの値は変更バッファのマージのようなバックグラウンド入出力を制御し、実際の作業を必要とするメインプロセスから入出力を奪うことがあります
      かなり忙しい120K QPSのMySQL DBを運用した経験では、どちらも触る必要はありませんでした。必要だと感じるなら、まずredo logが埋まるまでの時間とバッファプールのダーティページ比率を監視すべきです。おそらく別のパラメータを調整するほうがよいでしょう
      [0] https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.ht...
    • データベースでブロックサイズのアラインメントのような基本的なチューニングを行う際には、意外と確認すべき点があります。通常はレコードサイズを合わせるよう言われ、実際にはデータを格納するZFSファイルシステムのレコードサイズを小さくする方向につながります
      あるレベルではより効率的かもしれませんが、経験的には圧縮率を大きく低下させます
      興味深い二次効果として、ワークロードにもよりますが、ディスク帯域幅がボトルネックの場合はスループットがかえって悪化することがあります。圧縮のおかげで物理ディスクが処理できる以上の速度で読み書きできるのに、圧縮を損なうと読み書き帯域幅に悪影響が出る可能性があります
  • 数年前から Linux で ZFS を使い始め、全体的には順調だった。
    唯一驚いたのは、volblocksize のデフォルト値がほとんどの RAIDZ 構成にとってかなり悪いという点。生のディスク容量の 50% を失いたくなければ、値を大きくする必要がある。
    関連記事は以下。
    https://jro.io/nas/#overhead
    https://openzfs.github.io/openzfs-docs/Basic%20Concepts/RAID...
    https://www.delphix.com/blog/zfs-raidz-stripe-width-or-how-i...
    結局、ZFS 関連のスプレッドシートの一つまで見ることになった。
    ZFS overhead calc.xlsx
    https://docs.google.com/spreadsheets/d/1tf4qx1aMJp8Lo_R6gpT6...
    RAID-Z parity cost
    https://docs.google.com/spreadsheets/d/1pdu_X2tR4ztF6_HLtJ-D...

    • 個人的には、ミラー vdev の**効率 50%**は、単純さと大幅に向上する性能を考えれば妥当な代償だと思う。今では RAIDZ プールも拡張できるが、それでもはるかに複雑で、性能もそれほど良くない。
  • 若くて今よりさらに愚かだった頃、熱心なファンたちがオープンソースの NAS OS、おそらく FreeNAS と ZFS がどれほど素晴らしいかをたくさん書いている記事を読んだ。eBay でスペックがかなり低い中古の HP MicroServer を買い、自分が何をしているのかもよく分からないまま飛び込んだ。
    コミュニティフォーラムでいくつか質問したが、返ってきた答えの多くは「ドキュメントは読みましたか?」「RAM は十分ですか?」だった。
    そのドキュメントというのは読みにくいスタイルの PowerPoint プレゼン資料で、少し伝道師めいた文体で、前提知識が多く、定期的に更新されてもいなかった。必要な RAM 量も曖昧で、とにかく可能な限り多く積めという点に重点が置かれていた。
    結局、技術、過熱した雰囲気、自分の知識レベルに関するあらゆる危険信号を無視して、多くのデータを失った。学ぶことは多かった。

    • だいたいどれくらい前のことか覚えているのか気になる。ZFS は 2000 年代初頭からあり、FreeNAS は 2005 年に始まったと記憶している。
      ファイルシステムはずっと安定してきたし、ドキュメントもより明確になったと思う。
      それでも ext3 のような従来のジャーナリングファイルシステムより強力で高度である分、自分で自分の足を撃つ方法も増えている。
  • 後のためにいくつか補足すると、ZFS の冗長性はすべて vdev 層にある。zpool は 1 つ以上の vdev で作られ、いずれの場合でも zpool 内の vdev を 1 つでも失うと、その zpool は永久に破壊される。
    歴史的に RAIDZ、つまりパリティ RAID はディスクを追加して拡張することができなかった。RAIDZ を大きくする唯一の方法は、アレイ内の各ディスクを 1 台ずつより大きなディスクに交換することで、その再構築中にディスクが故障しないことを祈るしかない。
    かなり素人的な判断では、RAIDZ は RAIDZ2 や RAIDZ3 のようにディスク数が多い場合にだけ検討する。n<=6 で予算が許すなら、複数のミラー vdev を使う。本番環境では、複数の RAID の読み書き性能指標をもっと調べる必要がある。

    • ミラープールのほうが通常はより安全な方式なのはその通り。
      ただし、サイト全体のバックアップがあり、自分の能力と監視をかなり信頼できる場合に限って RAIDZ1 を勧められる。
      私の場合は 3x3 ドライブのプールがあり、スナップショットをラックの数 U 下にあるバックアップ先へ送っている。そのバックアップ先は毎日起動し、3x4 ドライブのプールを持っていて、これも RAIDZ1 だ。
      NAS でドライブ故障が起きたら、すぐにバックアップを開始してスナップショットを受け入れ、その後ドライブを交換するつもり。そうすれば、リシルバー中に 2 台目のドライブが故障してデータが飛ぶ可能性を最小化できる。
      本当に重要なデータはもちろん外部にも置いている。
  • 理解できないZFS の問題に遭遇している。ある zpool で zpool status が検出されたエラー一覧を出力するのだが、ファイルには出ず、常にスナップショット、そしておそらく削除済みスナップショットと思われる 16 進数の項目にだけ現れる。
    エラーとして表示されたスナップショットを削除して zpool scrub を 2 回実行すると、エラーは消え、スクラブもエラーを見つけない。zpool status はどのデバイスにもエラーを表示したことがない。
    ファイルにはエラーがなく、デバイスにもエラーがなく、スクラブでもエラーが検出されないのに、稼働中は 1 日に新しい「エラー」が 12 個ずつ zpool status に現れる。どうしてこんなことが起きるのか分からない。

    • 本当に良い質問。今すぐ重複する issue を自分で探す時間はないが、メーリングリスト https://zfsonlinux.topicbox.com/groups/zfs-discuss と GitHub issue https://github.com/openzfs/zfs/issues を探すか、質問できる。
      前者は変に見えるが、メーリングリストの通常の Web フロントエンドだ。
    • 同じ問題に遭遇している。ときどきファイルがスナップショットだけでなく、現在のファイルバージョンでも破損しているように見える。
      移動も変更もできず、削除だけ可能。なぜこうしたファイルが破損するのか全く手がかりがない。幸い、全部大きな Linux ISO だったので致命的ではなかった。