Soft Updatesの弱みを改善するジャーナリング

2010年4月24日(米国時間)、FreeBSD 9-CURRENTへSUJと呼ばれる機能が追加された。これはUFS2+Soft Updatesにジャーナリングの機能を追加するというユニークなもので、FreeBSD 9の目玉機能になるとみられている。2010年5月中旬にカナダで開催されたBSDCan2010およびFreeBSD Developer Summitで開発者からSUJの発表があったほか、このあたりのまとまった議論が実施された。とても興味深い内容であったためここで取り上げておきたい。

まずUFS2、Soft Updates、SUJ (Soft Updates Journaling)がそれぞれどういったものであるか簡単に説明しておく。UFS2はFreeBSDでデフォルト採用されているファイルシステム。BSD UFS(FFS)を時代に合わせて改善してきたもの。シンプルな構造で高性能。Soft Updatesは1998年にFreeBSDに追加されたメタデータの依存トラッキングシステム。メタデータをディスクに書き込むのではなくオンメモリですべて処理するというもので、メタデータの一貫性を保ちつつ処理の高速化を実現。UFS2と組み合わせて使うことで高い性能を発揮する。

SUJはSoft Updatesにジャーナル機能を追加したもの。クラッシュしたあとでもディスクは正常な状態にあるが、2つだけメタデータの不整合が発生する。開放されたものが開放されていないとして残るというものだ。オンメモリで処理しているため、書き込みが実施されてない部分にこの不整合が発生する。SUJはこの不整合を瞬時に復旧させるためのジャーナル機能。最大でも16MBしか消費しないジャーナルで、fsck(8)のきわめて高速な実行を可能にする。

ほかのファイルシステムの利点と欠点、FreeBSDのユニークな採用

ファイルシステムのメタデータ整合性を保つ方法はいくつかある。BSDCan2010でMarshall Kirk McKusick氏から発表された資料にそのあたりが簡潔にまとまっている。簡単にまとめると次のとおり。

メタデータ同期方式 利点と欠点
同期書き込み 単純で効果的。ただし、作成と削除を繰り返すようなアプリケーションにとっては遅いファイルシステム。クラッシュ後のリカバリにも長い時間が必要
非揮発性RAM すべての操作がメモリの速度で動作するためきわめて高速。クラッシュ後のリカバリも迅速に完了する。半面、ハードウェアがきわめて高価で、ほとんどのマシンでは採用されていない
ジャーナリングとロギング 高負荷時に作成や削除を繰り返すような操作をしても遅くならない。クラッシュ後のリカバリも高速。半面、追加のI/Oが発生するとともに、負荷が低い状況ではあまり速度面での恩恵は受けられない
コピーオンライト ZFSやLFS、WAFLなどで採用している方式。スナップショットの実現が簡単で、どの状態でも一貫性が保たれるという特徴がある。半面、ディスクのフラグメンテーションが発生しやすくメモリも大量に消費する
Soft Updates ほとんどの操作がメモリの速度で動作。I/Oを減らすことができ、クラッシュ後のリカバリも簡単。半面、コードが複雑になるほかバックグラウンド fsckに高い負荷がかかる。メモリ負荷も増える

最近の流行りはコピーオンライト。10年前はジャーナルが注目されていた。その当時、FreeBSDはSoft Updatesというユニークな方式を採用。ファイルシステムの信頼性を損なうことなく高速化を実現し、システムクラッシュ後に即時システムを実行できるという画期的なものだった。一点、一貫性を元に戻すために実行するバックグラウンドfsckが高いI/O負荷とメモリを持っていくという点を除いて。当時のディスクサイズでは問題化しにくかったが、TBクラスが標準の今では問題部分が目立つようになってきた。

Soft Updatesの仕組みとクラッシュあとの2つの不整合

Marshall Kirk McKusick氏の発表内容とSUJの論文はJournaled Soft-Updates (BSDCan2010)から入手できる。ここでは両資料に記載されている内容をベースに簡単に紹介していきたい。まずUFSにおけるファイルの削除として次の方法が紹介されている。

  1. ディスク上のディレクトリデータから対象となるファイル名を削除
  2. ディスク上の対象となるデータのinodeをゼロで埋める
  3. 対象ファイルのブロックをフリースペースビットマップへ開放

Soft Updatesはこれを次のようにオンメモリで実行するようにして、実際のディスクへアクセスしなくてもいいようにしている。

  1. カーネルバッファのディレクトリエントリをゼロで埋めてから、バッファに書き込みがあった段階で通知があるようにバッファに依存構造体を追加する
  2. ディレクトリバッファに書き込みがあったという通知を受けたらinodeブロックリストを保存し、カーネルバッファのinodeをゼロで埋めてから、バッファに書き込みがあった段階で通知があるようにバブロックリストを含む依存構造体を追加する
  3. inodeバッファに書き込みがあったという通知をうけたら、保存したブロックのリストをフリースペースビットマップへ開放

メタデータの操作がすべてオンメモリで処理されるため、メタデータを実際にディスクに書き込む前にシステムがクラッシュすると、不整合が発生する。システムがクラッシュした場合でもディスク状態は仕組み上は常に正当な状況にあるため実行する分には問題がないが、使われないデータが残ってしまう。次の2つのがそれだ。

  • フリーされたものの使用中とされているブロック
  • フリーされたものの使用中とされるinode

クラッシュ後すぐにファイルシステムを使い出しても問題ないものの、最終的にはこれらフリーしたものの使用中になってしまっている部分を解決してやる必要がある。これを処理するためにfsck(8)をバックグラウンドで実行するわけだが、ファイルシステム全部をチェックするためじつに長い時間がかかる。TBクラスのディスクが当たり前の現在になると、この方法はかなり苦痛をともなう。

SUJのパフォーマンス、圧倒的な復旧時間

そこでSUJだ。こうした不整合が発生する部分をジャーナルとして記録しておけばいいというのが基本的なアイディアだ。Soft Updatesによって発生した不整合部分だけを復元すればいいため、ジャーナルに記録するデータは少なくていい。最悪の場合でもファイルシステムのサイズに関係なく最大で16MBのジャーナル領域が必要になる程度だ。ジャーナルはファイルシステムのルートディレクトリに.sujournalという名前で作成される。ジャーナルに記録されるデータは次のとおり。

  • リンクカウントの増
  • リンクカウントの減
  • 参照されているアンリンク
  • ディレクトリオフセットの変更
  • フリーブロックとinodeのシリンダグループアップデート

SUJはほかのジャーナリングファイルシステムとはだいぶ違う状況にある。そもそもの目的が違うからだ。ジャーナルはあくまでもバックグラウンドfsckを不要にし、即座にfsckが終了するようにするために用意されている。BSDCan2010で示されたパフォーマンスチェックによれば次のようにシステムクラッシュ後のfsckの時間が短縮されていることが確認できる。

事例状況 SUJ ジャーナルを使わないfsck
80%が使用されている250GBのディスクで8並列buildworldを実行し、10分後にリセット 0.9秒 27分
892%使われている11TBのディスク(14ディスクを3ware RAID構成)でランダムに数百MB分の並列書き込みを実施したあとにリセット 1分以内 10時間

だいたい数秒で完了する。最悪の場合でも1分ほどしかかからない。BSDCanでは既存のソースコードと比較した次のデータも紹介された。

  • 既存の14の依存型に、さらに11の依存型を追加
  • Soft Updatesのソースコードサイズは6,409行から11,491行と倍近く増加
  • ジャーナルリカバリコードは2,500行。これに対しバックグラウンドfsckは6,100行

SUJを有効にすると当然ジャーナル書き込みが発生するためI/O負荷が増える。また、ジャーナルへの書き込み処理の間はほかの書き込みはブロックされるという性能低下もある。パフォーマンスは今後の課題とされており、チューニング後に正式な発表があるとみられる。なお今のところSUJは9での登場となり、6-STABLE、7-STABLE、8-STABLEにはバックポートされないとされている。パッチは提供されているため、同システムで利用したい場合には自分で適用させる必要がある。

後方互換性と将来展望

SUJに対応したファイルシステムを、SUJに対応していないFreeBSDカーネルでマウントすると、SUJを使っているというフラグがクリアされる。以前のFreeBSDカーネルからは従来のSUJのないファイルシステムとして利用できる。このため、SUJに対応していないFreeBSDカーネルでSUJに対応したファイシステムで利用した場合、SUJに対応したFreeBSDカーネルで利用するには、いったんファイルシステムをチェックしてから再度ジャーナルを作り直した方がいいようだ。

BSDCan 2010の開催に合わせて実施されたFreeBSD Developer Summitでは、SUJ以外にもUFSの次の取り組みをどうすべきかという議論もあった。仮にUFS3という言葉が使われていた。議論は多岐に渡りまだ方向性を確定する段階ではないが、UFS3への関心が高まっている点は興味深いものがあった。

またDevSummitの間、いろいろなシーンでZFSの名前を聞いたのも印象的だ。ファイルシステムレベルでの話から、アプリケーションレベルでの運用の話に至るまで、さまざまなシーンでZFSの活用や関心の高さが伺えた。