このページの目次

ZFS — カーネルの一部ではないが、避けては通れない

概要: ZFS アーキテクチャ (ZPL/DMU/SPA/ZIL/ARC) → COW トランザクションモデル → Linux VFS との統合 (SPL) → Btrfs/bcachefs との比較 → ライセンス問題

なぜ ZFS は Linux カーネルに含まれないのか

ZFS は CDDL ライセンスを使用しており、Linux の GPLv2 と互換性がありません。Sun/Oracle はデュアルライセンスを選択しなかったため、ZFS は Linux メインラインにマージされることはありません。

解決策⁠: OpenZFS は カーネルモジュール として提供され、DKMS を介してコンパイル・インストールされます。CDDL モジュールと GPL カーネル間のインターフェースは、SPL (Solaris Porting Layer) によって抽象化されます。ライセンス紛争の焦点は「派生作品に該当するか」という点にあり、これは法的なグレーゾーンであるため、ディストリビューションごとの対応が異なります:

  • Ubuntu: zfs-dkms を直接パッケージ化
  • Debian: contrib リポジトリで提供
  • Fedora/RHEL: 公式サポートなし(ユーザーが自行コンパイル)

ZFS アーキテクチャスタック

ZFS アーキテクチャスタック: ユーザー空間から物理デバイスへの呼び出し階層 ユーザー空間 — zfs(1) / zpool(1) / libzfs カーネル (OpenZFS モジュール) ZPL(ZFS POSIX Layer) — VFS インターフェース(i_op / f_op など) zfs_znode → 対応する inode → zfs_vnode_ops → VFS file_operations DMU(Data Management Unit) — トランザクションオブジェクトからブロックへのマッピング dnode→オブジェクト(ファイル/ディレクトリ/属性) · dmu_tx→トランザクション · dnode→ブロックポインタツリー(間接ブロック) ZIL(ZFS Intent Log) — 同期書き込みジャーナル zil_commit() → ZIL デバイス(SSD/HDD パーティション)への書き込み、fsync を高速化(同期書き込みは大トランザクションを迂回) ARC(Adaptive Replacement Cache) — 読み込みキャッシュ MRU(最近最も多く使用) + MFU(最近最も頻繁に使用) · page cache よりも先進的で、zfs_arc_max で設定可能 SPA(Storage Pool Allocator) — 物理デバイス管理層 metaslab→空き空間管理 · space map→ログ形式での追跡 · 割り当てポリシー first-fit / best-fit VDEV(Virtual Device) — RAID / デバイス抽象化 disk · mirror · raidz(1/2/3) · special(メタデータ/重複排除) · cache(L2ARC) · log(ZIL/SLOG)

COW トランザクションモデル

各書き込み操作:
  1. 新しいブロックを割り当て(対象の metaslab で空き領域を検索)
  2. 割り当てられたブロックに新データを書き込み
  3. dnode のブロックポインタを更新(旧ブロックではなく新ブロックを指す)
  4. dnode が変更された → dnode 自体も新しい位置に書き込む必要がある → 上位ポインタを更新
  5. 上位へ遡る → uberblock (ルート) が更新され → 原子操作で完了

重要: 全ポインタ更新は原子的である(uberblock の単一書き込み)
  → クラッシュ後は、旧状態か新状態のどちらかが見えるだけで、中間状態はない
  → これが「ジャーナルがない」という保証である(COW 自体が一貫性を保証する)

トランザクショングループ化 (TXG):
  ZFS は複数のシステムコールによる書き込み操作を 1 つのトランザクショングループ (TXG) に統合する
  約 5 秒ごとにコミットされる (zfs_txg_timeout)
  → 断片化を減らし、書き込みスループットを向上
  → fsync はこの遅延を回避する: ZIL を介して独立してコミットされる

SLOG と ZIL

ZIL (ZFS Intent Log):
  同期書き込み (O_SYNC / fsync) のアクセラレータ
  通常の非同期書き込み → 5 秒ごとの TXG → ZIL は不要
  同期書き込み → ZIL が個別に記録 → ユーザー空間へ返却 → 高速
         → 5 秒後に TXG がコミット → ZIL の記録は破棄可能

SLOG (Separate LOG):
  ZIL を専用デバイス(低遅延 NVMe SSD)に配置
  同期書き込みのレイテンシを HDD から SSD レベルに低下
  クラッシュリカバリ: ZIL + 最新の TXG をリプレイ → 完全な復旧

ZIL はライトキャッシュではない!
  操作ログのみを保存 → データは常に TXG によってメインストレージに書き込まれる
  停電で ZIL が消失 → 直近 5 秒間の同期書き込みのみが消失(非同期書き込みは影響を受けない)

Btrfs/bcachefs との比較

ZFSBtrfsbcachefs
ライセンスCDDLGPLv2GPLv2
カーネル統合DKMS モジュールin-treein-tree (6.7+)
COW常に適用メタデータは常に、データは任意常に適用
スナップショットZVOL, dataset レベルsubvolumesubvolume
RAIDraidz(1/2/3), mirrorraid0/1/10/5/6複数デバイス階層
ARC/L2ARCありなし (page cache を使用)なし
重複排除オンライン (メモリを大量消費)オフライン (ツールあり)なし
内蔵圧縮lz4, zstd, gzipzstd, lzo, zlibzstd, lz4, gzip
ストレージ送信/受信zfs send/recvbtrfs send/receive計画中

ZFS の明確な優位性は、成熟度(20 年以上の運用実績)と ARC 読み込みキャッシュです。Btrfs の優位性は、カーネルメインラインへの統合と、より軽量な RAID です。bcachefs はまだ新しく、安定性は検証待ちです。


デバッグ

# ARC の状態(zfs のインストールが必要)
cat /proc/spl/kstat/zfs/arcstats

# プールの状態
zpool status
zpool iostat -v 1

# 現在の TXG
cat /sys/module/zfs/parameters/zfs_txg_timeout

参照と拡張

  • OpenZFS ドキュメント⁠: https://openzfs.github.io/openzfs-docs/
  • ソースコード⁠: https://github.com/openzfs/zfs
  • 重要論文⁠:
    • "The Zettabyte File System" (Sun, 2003)
    • "The Adaptive Replacement Cache" (Megiddo & Modha, 2003)

キーワード: ZFS, DMU, ZIL, ARC, SPA, COW, SLOG, dnode, uberblock, TXG, CDDL, DKMS