EXT4のその先へ:なぜ本番サーバーをBtrfsに切り替えたのか

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

従来のファイルシステムの限界

EXT4は約10年の間、忠実に私を支えてくれました。ファイルシステム界のトヨタ・カローラのような存在で、信頼性が高く、予測可能で、実質的に壊れることがありません。

しかし、インフラが15の本番ノードにスケールするにつれ、限界が見え始めました。午前3時のメンテナンス時間、残り2%を切ったボリュームにわずか20GBの空きを作るために、クリティカルなパーティションをアンマウントしながら冷や汗を流す日々。2.4TBのデータベースのバックアップには6時間近くかかり、設定ミスが一つあるだけで、外部イメージングツールを使った苦痛を伴うフルリストアを余儀なくされていました。

6ヶ月前、私はメインスタックをBtrfsに移行しました。私が求めていたのは、即時リカバリ、柔軟なストレージプール、およびネイティブなデータ整合性を備えたシステムでした。長年、数十台のVPSインスタンスを管理してきた経験から、闇雲に切り替えたわけではありません。本番データに信頼を置く前に、3週間かけてI/Oパターンのベンチマークを行い、停電のシミュレーションを繰り返しました。ここでは、Btrfsを本番環境で半年間運用してきた現実をお伝えします。

コアコンセプト:Copy-on-Writeの威力

Btrfs(B-Tree Filesystem)は、私たちが慣れ親しんできたファイルシステムとは異なる仕組みで動いています。それは「Copy-on-Write (CoW)」というメカニズムを利用しています。EXT4がデータをその場で上書きし、古いバージョンを事実上消去するのに対し、Btrfsは変更されたデータをまず完全に新しいブロックに書き込みます。書き込みが成功して初めて、新しい場所を指すようにメタデータが更新されます。この設計上の選択こそが、このファイルシステムが提供するほぼすべての高度な機能を可能にしているのです。

サブボリューム vs 固定パーティション

以前はスペースの管理はゼロサムゲームでした。もし /var に100GBを割り当てて満杯になった場合、/home で500GBが遊んでいても、リスクのある再パーティション作業を行わない限り、その空き容量に触れることはできませんでした。Btrfsはサブボリュームを使用することで、これらの境界を無視します。サブボリュームは、独立したファイルシステムのように動作する高機能なフォルダだと考えてください。これらは一つの空き容量プールを共有します。データベースが今日、さらに10GB必要になれば、共通プールから取得するだけです。アンマウントは必要ありません。

スナップショット:即時のセーフティネット

スナップショットは、システム管理から「あ、しまった」という瞬間を取り除いてくれます。CoWアーキテクチャのおかげで、スナップショットの作成はほぼ一瞬です。実際にはデータをコピーせず、単にメタデータの現在の状態を記録するだけです。1TBのサブボリュームのスナップショット作成には約0.2秒しかかからず、ファイルを変更し始めるまで追加のスペースは一切消費しません。今では、apt upgrade や Nginx の設定変更を行う前には、必ずスナップショットを撮るようにしています。

実践:Btrfsの実装

セットアップには btrfs-progs パッケージが必要です。UbuntuやDebianでは apt install btrfs-progs を、Fedoraでは dnf install btrfs-progs を実行してください。

1. ファイルシステムの作成

/dev/sdb に新しいディスクがある場合、フォーマットは簡単です。ラベルを使用して /etc/fstab を読みやすくしましょう:

sudo mkfs.btrfs -L production_storage /dev/sdb

2. サブボリュームによる整理

私は、データタイプごとに特定のサブボリュームを作成することを好みます。これにより、きめ細かなスナップショット作成や、それぞれに異なるマウントオプションを適用することが可能になります。

# メインドライブのルートをマウント
sudo mount /dev/sdb /mnt/btrfs_root

# Webルートとデータベースバックアップ用のサブボリュームを作成
sudo btrfs subvolume create /mnt/btrfs_root/www
sudo btrfs subvolume create /mnt/btrfs_root/db_backups

# 作業内容を確認
sudo btrfs subvolume list /mnt/btrfs_root

3. 透過的圧縮(SSD의 寿命を延ばす)

透過的圧縮は、私のロギングサーバーにとって大きなメリットでした。Btrfsはカーネルレベルで圧縮を処理するため、アプリケーション側はその存在すら意識しません。私は、スペースの節約とCPU使用率の低減のバランスが完璧な zstd を使用しています。私の環境では、/var/log ディレクトリが45GBからわずか18GBへと、60%も削減されました。

有効にするには、/etc/fstab に以下を追加します:

LABEL=production_storage /data btrfs defaults,compress=zstd:3,autodefrag 0 0

これは単にスペースを節約するだけでなく、NANDセルへの物理的な書き込み総数を減らすことで、SSDの寿命を延ばすことにもつながります。

4. 障害を数秒で復旧する

本番環境のWebアプリのコードを1行でも触る前に、読み取り専用のスナップショットを作成します。もし問題が発生しても、原因究明に時間を費やすことはしません。ただ、元に戻すだけです。

# タイムスタンプ付きの読み取り専用スナップショットを作成
sudo btrfs subvolume snapshot -r /mnt/btrfs_root/www /mnt/btrfs_root/www_pre_update_$(date +%F)

# 復元するには、壊れたサブボリュームをスナップショットと入れ替える
sudo mv /mnt/btrfs_root/www /mnt/btrfs_root/www_broken
sudo btrfs subvolume snapshot /mnt/btrfs_root/www_pre_update_2024-05-20 /mnt/btrfs_root/www

システムのヘルスチェックを維持する

BtrfsはEXT4のように「設定したらおしまい」というツールではありません。パフォーマンスの低下を防ぐために、時折メンテナンスを行う必要があります。私は毎月のメンテナンススケジュールに2つのタスクを自動化して組み込んでいます。

スクラビング:ビットロット(データの腐敗)との戦い

Btrfsはすべてのデータビットに対してチェックサムを保存します。「スクラブ」はすべてのブロックを読み取り、チェックサムと照合して検証します。先月、スクラブによって、寿命が近づいていた2TBのSSDで4つのチェックサムエラーが検出されました。BtrfsのRAID構成で運用していたため、ファイルシステムは正常なミラーを使用して、それらのエラーを自動的に修復してくれました。

sudo btrfs scrub start /data
sudo btrfs scrub status /data

バランシング

多くの削除作業やスナップショットのローテーションを繰り返すと、ファイルシステムの内部チャンクの割り当てが非効率になることがあります。バランシングはデータを再分配して、スペースを回収します。私は通常、処理を迅速に終わらせるために、使用率が50%未満のチャンクを対象に実行しています。

sudo btrfs balance start -dusage=50 /data

6ヶ月後の結論

Btrfsへの切り替えは、今年私が行った中で最高のインフラ改善でした。即時ロールバックを実行できる機能のおかげで、デプロイ失敗の際に少なくとも3回は窮地を救われました。メタデータの監視や定期的なスクラブ実行は必要ですが、サブボリュームの柔軟性を知ってしまうと、従来のパーティション管理はスマートフォンの時代にガラケーを使っているような気分になります。

固定されたディスク制限や遅いバックアップに疲れているなら、まずは小さく始めてみてください。セカンダリデータドライブをBtrfsでマウントし、スナップショットを試してみるのです。50GBのリストアが1秒足らずで終わるのを一度目の当たりにすれば、もう元には戻りたくなくなるはずです。

Share: