Coda 分散ファイル・システム

Peter J. Braam
School of Computer Science,
Carnegie Mellon University

手引き

Coda 分散ファイル・システムは M. Satyanarayanan at Carnegie Mellon University のグループで開発された最先端の試験的なファイルシステムです。他のシステムにはない、多くの機能(:モバイル・コンピュータ)を備えた Coda にはたくさんの人が関わっています。
 

Fig 1: Coda のロゴ (Illustration by Gaich Muramatsu)

たぶん、いくつかの単語で混乱することになると思いますが、始めます。

分散ファイルシステム

分散ファイルシステムは、複数のサーバマシン上にあるファイルを記憶していて、クライアントマシンに対してサーバが普通のファイルにアクセスするようにアクセスすることができます。ファイルサーバを使う利点は: たくさんのマシンがサーバに接続できるので、ファイルを広い範囲で利用できます。個々のクライアントにファイルをコピーを配るよりも、一つの記憶装置でファイルを共有する方が楽です。情報のバックアップと安全は、サーバをバックアップするだけなので簡単です。 サーバには大きい保存領域があり、それをクライアントに用意するのはコスト的にも実用的ではありません。従業員が共有するドキュメントを考えれば、分散ファイルシステムの実用性は、はっきりしています。また、それ以上の効果もあるでしょう。例えば、共有するアプリケーション・ソフトウェアが考えられます。いずれにしても、システム管理は簡単になります。

便利な分散ファイルシステムの設計では、たくさんの問題に直面します。ネット上で多くのファイルを転送すると、すぐに重いパフォーマンスとレイテンシ、ネットワークのボトルネック、サーバのオーバーロードにつながります。データのセキュリティも問題になります: クライアントが情報へのアクセスを認証されたことをどうやって確認するのか、そして、ネットワークでデータを探られるのをどうやって防ぎますか?設計で直面する二つの更なる問題は失敗につながります。しばしばクライアントマシンはネットワークに接続しているものより信頼性があり、ネットワークの失敗はクライアントを使えなくします。同じようにサーバの失敗は好ましいものではなく、クライアントは重要な情報にアクセスできません。Coda プロジェクトはこれらの問題に注意を払い、研究のプロトタイプとしてそれを実現しています。

Fig. 2 サーバ制御のセキュリティ (Illustration by Gaich Muramatsu)

Coda は元々 Mach 2.6 に実装されていたもので、最近 Linux、NetBSD、FreeBSD に移植されました。Michael Callahan は Windows 95 に Coda の大部分を移植していて、私たちは Coda を Windows NT に移植実現をする可能性を検討しています。現在のところ私たちの作業は移植と、システムをより強固なものにすることです。新しい機能が実装されて(例えば、書き込みのキャッシュ、セル)、ある部分では Coda は再構成されています。ネット上のユーザからは既に好意的な反応を得ていて、これを続行するつもりです。おそらく Coda はポピュラーなものになって、自由に利用できる分散ファイルシステムとして広く使われるようになるでしょう。

クライアントの Coda

Coda が Linux ワークステーションのクライアントで走っていると、mount を実行した時に /coda 下にマウントされた --of type ``Coda'' -- のファイルシステムを表示します。サーバからクライアントが利用できる全てのファイルがこのディレクトリ以下にあって、全てのクライアントが同じネーム空間を見ています。クライアントは``Coda''に接続して、個々のサーバは不可視になっています。 サーバ毎、エクスポート basis 毎に行われるような、NFS ファイルシステムをマウントするのとは全く異なります。ほとんどの場合、Macintosh の Appleshare だけでなく、普通の Windows システム (Novell と Microsoft's CIFS) でも、ファイルはボリューム毎にマウントされます。まだグローバルのネーム空間は新しくありません。Andrew ファイルシステムは Coda の先祖にあたり、/afs 以下に全てのファイルを保存します。Coda のアイデアの先駆です。似たものとして OSF からの分散ファイルシステム DFS/DCE があり、一つのディレクトリにファイルをマウントします。Microsoft の新しい分散ファイルシステム (dfs) は、一つのファイルツリーで全てのサーバの共有を行うようにします。これは Unix のオートマウント・デーモンとイエロー・ページによるものと似ています。単一のマウント・ポイントはなぜ有利なのでしょうか?全てのクライアントは等しく設定されて、ユーザは常に同じファイルツリーを見ています。大きなインストールでは基本的なことです。NFS では、クライアントがサーバリストを更新して /etc/fstab にエクスポートされたディレクトリを書き出してやる必要がありますが、Coda ではクライアントが単に root ディレクトリ /coda を捜すだけです。新しいサーバや共有が追加されると、クライアントは /coda ツリーの中でそれを自動的に捜します。

サーバに対するネットワークの接続が困難なときに Coda がどのような操作を行うかを理解するには、単純なファイルシステム操作を調べることです。 Coda ファイルのコンテンツを表示するために、次のように入力するとします: ``cat /coda/tmp/foo''。何が起きているのでしょう?cat プログラムはファイルに関するシステム・コールを作ります。システム・コールはプログラムがカーネルにサービスを頼むことによる操作です: 例えば、ファイルを開くときにカーネルはファイルの inode を捜すルックアップ操作を行って、プログラムにファイルハンドルを返します。inode はファイルにあるデータにアクセスするための情報を持っていて、カーネルによって使われます。ファイルハンドルは開始プログラムです。開始コールはカーネルのバーチャル・ファイルシステム (VFS) に入って、/coda ファイルシステムにあるファイルに対するリクエストが認識されると、カーネルで Coda のファイルシステム・モジュールに渡されます。Coda は非常に小さなファイルシステム・モジュールです: 最新の、VFS からの返答されたリクエストのキャッシュを維持します。しかし、そうでなければ Venus と呼ばれる Coda キャッシュ・マネージャにリクエストを譲ります。Venus は tmp/foo でクライアントのディスク・キャッシュを確認して、キャッシュの失敗があればサーバに tmp/foo を要求します。ファイルがロードされたときに、Venus はシステムコールからプログラムを順にリターンするカーネルに応答します。概要は次のようなイメージです。 (figure 3).

Fig 3. Client/Venus/Vice

図はユーザプログラムが、どのようにしてシステムコールを通じたカーネルからサービスを求めるのかを示しています。 カーネルは、キャラクタ・デバイス /dev/cfs0 から Venus がリクエストを読めるようにすることによって、Venus にそれを送ります。 Venus はサーバに聞いてそのキャッシュを見るか、あるいは切断を認識して切断モードでサービスするかして、リクエストに答えようとします。 ファイルを持っているなんらかのサーバにネットワーク接続がない時に切断モードが作動します。普通これは、ネットワークを外した時のラップトップ、あるいはネットワークの失敗で生じます。サーバで失敗したときも切断操作になります。

カーネルが最初に Venus に対して開始リクエストをパスすると、サーバにつなぐ遠隔プロシージャ・コールを使って Venus はサーバから空のファイルを取ってきます。それからキャッシュ領域 (currently/usr/coda/venus.cache/) にあるコンテナ・ファイルとしてファイルを保存します。そうすると、ファイルはローカルディスクにある普通のファイルになって、ファイルに対する読み書き操作は Venus にはつながないで、ローカルファイルシステム (Linux では ext2) によって完全に扱われます。Coda の読み書き操作はローカルファイルと同じスピードで行われます。ファイルが二回目に開かれると、サーバに取りに行くことはしないで、ローカルコピーが直接使われます。全ての属性(所有者、パーミッション、サイズ)だけでなくディレクトリファイル(注: ディレクトリは単にファイル)は Venus にキャッシュされ、Venus はファイルがキャッシュにあればサーバに接続しないで操作を続行します。ファイルが修正されて閉じられると、Venus は新しいファイルを送信することによってサーバを更新します。ディレクトリを作ったり、ファイルやディレクトリを消したり、(シンボリック)リンクを作ったり消したり、ファイルシステムを変更するような操作も、サーバに伝わります。

Coda は、クライアントで必要となる全ての情報をキャッシュして、更新されたファイルシステムだけをサーバに知らせます。修正は、ごくまれにある、ファイルへの ``read only'' アクセスの比較だけです。今後は、クライアント・サーバの通信を最小限にするという、はるかな道へ向かっています。極端なキャッシュデータに対するこれらのメカニズムは、AFS と DFS で実装されていますが、他のほとんどのシステムは基本的なキャッシュです。Coda がどのようにして、つじつまが合うようにファイルを維持しているのかは後でわかりますが、最初は切断操作のサポートに必要なことについてです。

キャッシュから切断操作へ

もともと、Coda の切断操作は、プロジェクトの研究目的の一つとしてありました: ネットワーク失敗時でもファイルシステムを提供することです。 CMU キャンパスで 80 年代後半に 1000 のクライアントをサポートしていた AFS は非常に大きなものになって、ネットワークの停止やサーバの失敗は、ほとんどいつもやっかいなことになっていました。モバイル・クライアントの急速な普及に対応するために時間のかかった試みが為されて、Coda はネットワークとサーバの失敗をサポートし、モバイルクライアントでも使えるようになりました。

Coda がデータへのアクセスを提供するために必要とされる全ての情報をキャッシュすることは、前に書きました。ファイルシステムに対して更新が行われると、 それをサーバに伝える必要があります。普通の接続モードでは、そのような更新はサーバと同調して行われます。すなわちクライアントで更新が終わるとサーバでも更新されるということです。もしサーバが利用できないか、クライアント・サーバ間のネットワークが失敗すると、その操作はタイムアウト・エラーか失敗に終わります。何かが実行される場合もあります。例えば、キャッシュにないファイルをサーバから取ってこようとしたときに、ネットワークの接続なしでは実行できません。 そのような場合、エラーは呼び出しプログラムに報告されます。しかし、たいていタイムアウトは以下のように整然と行われます。

切断されたコンピュータのサポートや、ネットワークの失敗での操作のために、Venus は更新がタイムアウトになってもユーザに失敗を通知しません。 代わりに Venus は問題となったサーバが利用できず、更新がクライアントで行われることを認識します。切断の間、ディスクと頻繁に接触する CML (client modification log) に全ての更新が保存されます。ユーザは Coda が切断モードになっても全く気が付きません。サーバに再接続することで、Venus は CML を再構成します: サーバでのファイルシステムの更新をサーバに再生させて、その結果サーバを最新のものにします。さらに、CML は効率的になります - 例えば、もしファイルが最初に作られて、移動されると無効になります。

切断操作に関して非常に大事なことが二つあります。一つは保存するファイルの概念です。Venus は切断の間、Venus cannot server a cache miss なので、もし重要なファイルを最新なものにしたいなら、頻繁に最新の更新をサーバが送るようにするのが良いです。そういうファイルはユーザの保管データベースにあります(ユーザのファイルアクセスの``スパイ活動''によって自動的に作られます)。保管ファイルの更新はホード・ウォークと呼ばれます。実際にラップトップは、X11 ウィンドウシステムのバイナリとライブラリ、あるいは Wabi と Microsoft Office のような莫大な大きさのシステム・ソフトウェアを保管します。ファイルはファイルなので、以前からのアプリケーションもちゃんと動きます。

Fig 4: Hoarded Files are ``sticky'' in the cache. (Illustration by Gaich Muramatsu)

二つ目の問題は、再構築の間に、他のクライアントが切断の間にファイルを修正して、サーバに送り出されたときです。これは修復する必要あり、ローカル/グローバル・コンフリクトと呼ばれます。修復はアプリケーションの指定したリゾルバ(あるクライアントがカレンダーファイルに月曜日のアポイントを入れて、他のクライアントが火曜日のアポイントを入れても、分解できないコンフリクトを作らない)によって自動的に行なわれることがあります。ときどき、ごく希に手動でコンフリクトを修正する必要があります。

金曜日に、大量のソースコードが保管されたラップトップを持ってオフィスを後にするとします。山小屋でハッキングした後に、月曜にかったるいオフィスに戻ってきて(もちろん10日間)、週末の間に行った更新を再構成します。これがモバイル・コンピューティングです。

Fig. 5 failure resilience methods

Volumes, Servers and Server Replication

ほとんどのネットワーク・ファイルシステムで、サーバは標準的なファイル構造が約束され、クライアントにディレクトリをエクスポートします。サーバにあるファイルのディレクトリはクライアントにマウントされ、Windows jargon や UNIX のネットワーク・ファイル・システムではネットワークの共有と呼ばれます。これらのシステムでは、既にマウントされたネットワークのボリュームの中に、さらに分散したボリュームをマウントするのは現実的ではありません。パーティションやディレクトリ、共有の設定にはリスクが伴います。Coda の仕組みは実質的に異なります。

Coda サーバにあるファイルは一般的なファイルシステムには保存されません。その仕組みは以下の通りです。Coda サーバ・ワークステーションのパーティションは ファイルサーバを利用できるようになっています。これらのパーティションはボリュームの中にグループ化されたファイルを持っています。それぞれのボリュームはファイルシステムのようなディレクトリ構造を持っています: すなわち、ボリュームの root ディレクトリとその下にあるツリーです。ボリュームは一般にパーティションよりも小さいですが、一つのディレクトリよりは大きい、ファイルの論理ユニットです。例えば、ユーザのホームディレクトリは一つの Coda のボリュームになり、同じように Coda のソースは一つのボリュームになります。普通、一つのサーバは数百のボリュームを持っていて、平均的なサイズはおよそ 10MB です。 システム管理の観点から見ると、ボリュームというのはファイルデータを扱いやすいユニットです。

Coda はボリュームとディレクトリの情報、アクセス制御リスト、生パーティションにあるファイル属性情報を持っています。これらは速度と一貫性を持たせるための、復元可能な仮想メモリパッケージ(recoverable virtual memory package (RVM))を基にしたログを通じてアクセスされます。ファイルデータだけはサーバのパーティションにあるファイルにあります。RVM にはトランザクションのサポートがあります - サーバがクラッシュした場合にシステムが比較的楽にまともな状態にリストアされます。

ボリュームは名前と id を持っていて、/coda 以下のどこかにマウントすることが可能です。例えば、u.braam というボリューム以下を /coda/usr/braam にマウントするためには、cfs makemount u.braam /coda/usr/braam というコマンドが必要です。Coda は存在するディレクトリのマウントポイントは許可しません。マウントのプロセスで新しいディレクトリを作るようになっています。存在するディレクトリのトップに Unix ファイルシステムをマウントすることで生じる混乱を避けるためです。Macintosh と Windows でよく使われる``network drives and volumes''の作成と似ているように見えますが、決定的に違うのはマウントポイントがクライアントには見えない点です: 普通、/coda 以下のディレクトリに現われます。ある一つのボリュームには root ボリュームになる特権があり、起動時に /coda にマウントされるボリュームです。

Coda は Fid と呼ばれる 3 つの 32 ビット整数でファイルを認識します: VolumeId、VnodeId、Uniquifier の 3 つです。VolumeId はファイルのあるボリュームを識別します。VnodeId はファイルの``inode''数で、uniquifier は変換に必要とされます。Fid は Coda サーバのクラスタな中で固有のものです。

Coda は読み書きの複製サーバです。すなわち、サーバのグループはクライアントにファイルデータを分配して、更新はこのグループ内で全てのサーバに対して行われます。これの優れた点はデータの高い利用度です: もしあるサーバで失敗しても、クライアント側ではしくじることなしに、他のサーバが引継ぎます。ボリュームは VSG (ボリューム・ストレージ・グループ:Volume Storage Group) と呼ばれるサーバのグループに保存されます。

複製されたボリュームでは、VolumeId は複製された VolumeId になります。複製されたボリューム id はボリューム・ストレージ・グループと、それぞれのメンバーのローカルボリュームをまとめます。

VSG は複製されたボリュームのコピーを持つサーバのリストです。

それぞれのサーバのローカルボリュームがパーティションとファイルを持ったローカルボリューム id 、サーバのメタデータを定義します。

Venus がサーバにあるオブジェクトにアクセスするなら、まずファイルを持っているボリュームの VolumeInfo を捜す必要があります。 VolumeInfo には、サーバのリストと、ボリュームが知られているそれぞれのサーバのローカルボリューム id の情報があります。 ファイルのための VSG にあるサーバとの通信は、読み込みが一度で書き込みは複数です: VSG にある一つのサーバからファイルを読んで、利用できる AVS のメンバー、AVSG の全ての更新を伝えます。Coda はマルチキャスト RPC を用いていて、多くの書き込みの更新はパフォーマンスにはあまり影響しません。

ボリューム情報を最初に取り出すオーバーヘッドも見かけ倒しです。ボリューム情報に対するルックアップが一度あって、ファイルのアクセスは非常に短くなります。マウントしている大きなディレクトリより、ずっと近くにボリュームの root があるからです。

サーバの複製で切断のような操作には、分解と修復を必要とします。VSG にあるサーバはネットワークやサーバの不具合のせいで分離されます。この場合、特定の対象に対する AVSG は VSG よりも確実に小さくなります。更新は全てのサーバに伝えられますが、AVSG のメンバーだけはその結果、グローバル(すなわち server/server)なコンフリクトを持ち込むことになります。

Fig 6: AVSG vs. VSG (Illustration by Gaich Muramatsu)

オブジェクトやその属性を取り出す前に、Venus は利用出来る全てのサーバからバージョン・スタンプをリクエストします。サーバがファイルの最新コピーを持っていないことを検出すると、差異を自動的に解析しようとするプロセスを開始します。これが失敗すると、ユーザは手動で修復しなければなりません。クライアントによって開始されたにも関わらず、解析は完全にサーバによってハンドルされます。

サーバの複製と分解は素晴らしいものです。いくつかのサーバではしばしばディスクの故障で苦しんでいます。サーバを修復するのに必要なのは、新しいドライブに置いて、Coda に"それを解析しろ"と言えばいいのです。分解のシステムは他のサーバについて新しいディスクを最新のものにします。

Coda in action

Coda は CMU ではコンスタントに使われています。多くのクライアントが普段のファイルシステムとして、そして常時接続ではないアプリケーションのために、Coda を(Coda の)開発作業に使っています。以下の二つのシナリオは Coda の機能を非常にうまく利用しています。 私達は複数の Wabi のライセンスと関連する Windows のソフトウェアを購入しました。Wabi では MS の Powerpoint を使うことができます。Coda には MS Office をインストールした Wabi と Windows 3.1 があり、クライアントで共有しています。もちろん、.ini ファイルでユーザを指定していますが、ライブラリとアプリケーションに関しては自由です。ソフトウェアが入っているので、プレゼンテーションのときにネットワークに接続していないラップトップ機でソフトウェアを使うことができます。コンファレンスでよく使います。

ここ数年、ユーザのデータを無くしていません。サーバではしばしばディスクが故障しますが、ボリュームに置いてあるものは複製が作られるので、空のディスクと取り替えて、修復するサーバをアップデートさせればOKです。 新しいディスクが適当な場所にあれば、作用するファイルツリーで``ls -lR''を実行するだけでOKです。修復されるサーバにファイルが見つからないのがわかると、まともなサーバから新しく修復されるサーバにファイルを転送します。

Coda が持つ魅力的な機能はまだまだあります。

FTP のミラーサイトは Coda のクライアントにすると良いでしょう。たくさんのミラーを持っている ftp.redhat.com を例に見てみましょう。 それぞれのミラーは Perl スクリプトを動かして RedHat のツリー全体を見て何が更新されているのかを見て、それを取ってきます - ミラーが必要かどうかに関わらずです。Coda を用いた場合では、これと対照的です。ミラーサイトは Coda のクライアントになりますが、RedHat だけが書き込み許可を持っています。RedHat がパッケージをアップデートすると、Coda サーバはファイルに変更があったことをミラーサイトに通知します。ミラーサイトはこのパッケージを取ってきますが、それは誰かがこのパッケージを取ってこようとした時だけです。

WWW の複製サーバも Coda のクライアントになります。たくさんの ISP が 2、3 の WWW 複製サーバに悪戦苦闘しています。たった一つの http サーバではアクセスが多すぎるのです。ドキュメントの共有に NFS を使うと、パフォーマンスの問題を考えなくてはなりません。それで、個々のサーバに手動でファイルをコピーする、といったことが頻繁に行われます。それぞれのサーバが Coda クライアントになって、そのキャッシュにデータを持つことによって、Coda はレスキューを実現します。これで、ローカルディスクの速さでのアクセスを実現します。オフラインのウェブ情報をアップデートする ISP のクライアントとこれを組み合わせて、モバイルクライアントでもアプリケーションを持つことになります。

ネットワーク・コンピュータは、キャッシュとして Coda を利用することで劇的にパフォーマンスが改善します。ネットワーク・コンピュータに対するアップデートはサーバで利用できるようになることで、自動的に行われます。そして、コンピュータの大部分は、再起動の後でもネットワークの通信がないままで操作します。

現在行っている開発作業は Coda の特性の改良が主です。当然、検索システムにある粗い部分はゆっくり取り除かれています。ライトバック・キャッシングが追加され、Coda の操作は速くなっています。切断操作はライトバック・キャッシングの最後の手段です。接続操作の間にライトバック・キャッシングのためにこのメカニズムを利用します。Kerberos サポートが追加されています。Coda をサポートしているネットワーク・プロトコルはこれを容易にします。同時にクライアントが一つ以上の Coda クラスタに接続できるようなセルを持てるようにする予定です。さらに多くのシステムで Coda を使えるようにもします。

Coda の入手

ftp なら、Coda は ftp.coda.cs.cmu.edu から入手できます。ソースの tar 塊だけでなく、Linux の RPM パッケージもあります。Coda のカーネルサポートは Linux 2.2 です。www.coda.cs.cmu.edu のウェブサイトには、メーリングリスト、マニュアルの情報があり、検索もできます。