目次


ネットワーク・ファイルシステムと Linux

常に有用でありながら進化し続ける NFS

Comments

ネットワーク・ファイルシステムとは、ファイルシステムのネットワーク抽象化のことです。ネットワーク・ファイルシステムでは、リモート・クライアントが、ローカル・ファイルシステムにアクセスするのと同じように、ネットワークを介してファイルシステムにアクセスすることができます。この類のシステムは NFS が登場する以前からあったものの、NFS はそのなかで最も強力なネットワーク・ファイルシステムとなるまでに進化し、UNIX® で広範に使用されています。NFS では多数のユーザーが同じ 1 つのファイルシステムを共有できることから、データを中央に集め、必要なストレージを最小限にできるという利点があります。

この記事ではまず、NFS の略史として、その起源と進化の軌跡を説明します。その後、NFS のアーキテクチャーと今後の NFS の展望を詳しく探っていきます。

NFS の略史

最初のネットワーク・ファイルシステムは、1976年に DEC (Digital Equipment Corporation) によって開発された File Access Listener です。これは DAP (Data Access Protocol) の実装であり、DECnet プロトコル・スイートの一部でした。DEC では、TCP/IP のような独自のネットワーク・プロトコルに関するプロトコル仕様を公開していました。その 1 つが、DAP です。

NFS は、現在使われているような (IP プロトコルをベースとした) ネットワーク・ファイルシステムとして初めて登場したネットワーク・ファイルシステムであり、1980年代初頭に、Sun Microsystems 社内で開発された実験的なファイルシステムとして誕生しました。その高い評判から、NFS プロトコルは RFC (Request for Comments) 仕様として文書化され、NFSv2 として知られる仕様に進化しました。標準化された NFS は、他のクライアントおよびサーバーとの相互運用を可能にするというその機能のおかげで、急速な成長を遂げました。

標準としての NFS は、RFC 1813 で定義された NFSv3 に進化します。NFS はこのバージョンでこれまでになくスケーラブルなプロトコルとなり、大きなサイズのファイル (2GB を超えるサイズ)、非同期書き込み、そして転送プロトコルとして TCP をサポートすることにより、広域ネットワークを舞台とするファイルシステムの下地を作りました。NFS をエンタープライズ環境に躍進させたのは、2000年 の RFC 3010 (後に RFC 3530 へと改訂) です。Sun は NFSv4 に、強力なセキュリティーと併せ、ステートフルなプロトコルを導入しました (以前のバージョンでは、NFS はステートレスでした)。現在、(RFC 5661 で定義された) バージョン 4.1 の NFS には、分散サーバー環境での並列アクセスを目的としたプロトコル・サポートが追加されています (これが、pNFS と呼ばれる拡張機能です)。

NFS の進化の歴史を、それぞれのバージョンを文書化した RFC と併せて図 1 に示します。

図 1. NFS プロトコルの進化の歴史
NFS プロトコルの進化の歴史
NFS プロトコルの進化の歴史

驚くべきことに、NFS の開発は約 30 年もの間続いています。NFS は、極めて安定性 (そして移植性) に優れた、スケーラブルでハイパフォーマンスのエンタープライズ品質対応のネットワーク・ファイルシステムを代表するものです。そんな NFS は、ネットワークが高速化してレイテンシーが短縮されるなか、ネットワークを介してファイルシステムを提供する魅力的な選択肢であり続けるはずです。ローカル・ネットワーク環境でさえも、仮想化の流れから、より多くのモバイル仮想マシンをサポートするためにストレージのネットワーク化が進んでいます。NFS はこのような仮想インフラストラクチャーを最適化する最新のコンピューティング・モデルすらもサポートします。

NFS のアーキテクチャー

NFS が従うコンピューティング・モデルは、クライアント・サーバー・モデルです (図 2 を参照)。サーバーが共有ファイルシステムとストレージを実装し、そこにクライアントが接続します。クライアントは共有ファイルシステムに対するユーザー・インターフェースを実装し、クライアントのローカル・ファイル空間内にこの共有ファイルシステムをマウントします。

図 2. NFS のクライアント・サーバー・アーキテクチャー
NFS のクライアント・サーバー・アーキテクチャー
NFS のクライアント・サーバー・アーキテクチャー

Linux® 内で、複数のファイルシステムを 1 つのホスト (CD-ROM 上の ISO (International Organization for Standardization) 9660 やローカル・ハード・ディスク上の ext3fs など) で同時にサポートする手段となるのは、仮想ファイルシステム・スイッチ (VFS) です。VFS はリクエストの対象となっているストレージを判別した後、そのリクエストに対処するために必要なファイルシステムを判別します。そのため、NFS は他のあらゆるファイルシステムと同様、プラガブルになっています。NFS が他のファイルシステムと違う点は唯一、入出力 (I/O) リクエストがローカル側で対処できなければ、リクエストはネットワークを介してリモート側で対処されることです。

NFS を対象にしたリクエストが検出されると、VFS はそのリクエストをカーネル内の NFS インスタンスに渡します。NFS は I/O リクエストを解釈して NFS のプロシージャー (OPENACCESSCREATEREADCLOSEREMOVE など) に変換します。これらのプロシージャー (特定の NFS RFC に文書化されています) は、NFS プロトコル内での振る舞いを指定します。I/O リクエストから選択されたプロシージャーは RPC (Remote Procedure Call) 層の中で実行されます。RPC はその名前が示唆するように、システム間をまたがるプロシージャー・コールを実行するための手段です。RPC は NFS リクエストとそれに付随する引数をまとめてマーシャリングしてから該当するリモート・システムに送信します。その後、返されるレスポンスの管理および追跡を行い、そのレスポンスをリクエスト側に送信します。

さらに、RPC は XDR (External Data Representation) と呼ばれる重要な相互運用層を組み込みます。XDR によって、NFS に参加するすべてのシステムがデータ型に関して確実に同じ言語で対話することになります。ある特定のアーキテクチャーが行ったリクエストのデータ型の表現方式が、そのリクエストに対処するターゲット・ホストの表現方式と同じであるとは限りません。そのため XDR は、すべてのアーキテクチャーが相互運用してファイルシステムを共有できるように、データ型を共通表現方式 (XDR) に変換します。XDR は、float などの型のビット・フォーマット、そして固定長および可変長の配列などの型のバイト・オーダーを指定しています。XDR は NFS で使用されていることで最もよく知られていますが、1 つの共通したアプリケーション設定で複数のアーキテクチャーを扱う際には必ず役に立つ仕様です。

XDR でデータが共通表現に変換されたリクエストは、ネットワークを介して転送されます。その際のトランスポート層プロトコルとしては、初期の NFS では UDP (Universal Datagram Protocol) を使用していましたが、現在は信頼性を高めるために TCP が共通して使用されています。

サーバー側でも、NFS は同じように動作します。リクエストは (データ型をサーバーのアーキテクチャーに変換するため) RPC/XDR によりネットワーク・スタックに送られ、NFS サーバーに到達します。NFS サーバーの役目は、リクエストに対処することです。リクエストが NFS デーモンに渡されると、NFS デーモンはリクエストに必要なターゲット・ファイルシステム・ツリーを特定します。ローカル・ストレージ内の該当するファイルシステムにアクセスするために、再び VFS が使用されます。図 3 に、このプロセス全体を示します。この図では、サーバーのローカル・ファイルシステムが典型的な Linux ファイルシステム (ext4fs など) であることに注意してください。したがって、NFS は従来の意味でのファイルシステムではなく、リモートからファイルシステムにアクセスするためのプロトコルであると言えます。

図 3. NFS スタックのクライアントとサーバー
NFS スタックのクライアントとサーバー
NFS スタックのクライアントとサーバー

高レイテンシーのネットワークの場合、NFSv4 はいわゆる複合プロシージャーを実装します。基本的に、複合プロシージャーはネットワークを介したリクエストの転送の負担を最小限に抑えるために、複数の RPC 呼び出しを 1 つのリクエストに統合します。さらに、レスポンス用のコールバック・スキームも実装します。

NFS プロトコル

クライアントの観点では、NFS 内で行われる最初の操作はマウントと呼ばれます。マウントとは、リモート・ファイルシステムをローカル・ファイルシステム空間にマウントすることを意味します。このプロセスは、Linux システム・コールである mount の呼び出しとして始まり、VFS を介して NFS コンポーネントにルーティングされます。マウント用のポート番号が設定されると (これには、リモート・サーバーへの get_port リクエストによる RPC 呼び出しが使用されます)、クライアントは RPC による mount リクエストを行います。このリクエストは、クライアントと mount プロトコルを実行する特殊なデーモン (rpc.mountd) との間で行われます。このデーモンは、クライアントのリクエストを、サーバーに現在エクスポートされているファイルシステムのリストに照らし合わせます。リクエストされたファイルシステムがリストに存在し、クライアントがアクセスできる場合には、RPC による mount への応答によってファイルシステムに対するファイル・ハンドルが設定されます。クライアント・サイドは、リモート・マウント情報をローカル・マウント・ポイントと一緒に保管し、I/O リクエストを実行できるようにします。このプロトコルにはセキュリティー上の問題が発生する可能性があることから、NFSv4 ではこの補助的 mount プロトコルを内部 RPC 呼び出しに置き換えて、マウント・ポイントを管理しています。

ファイルを読み取るには、まずはそのファイルを開かなければなりません。RPC には OPEN プロシージャーが含まれていないため、クライアントはマウントされたファイルシステム内にディレクトリーとファイルがあるかどうかを単純にチェックするだけです。クライアントはまず、ディレクトリーに対する RPC リクエストとして GETATTR を発行します。このリクエストによって、ディレクトリーの属性が含まれるレスポンスが返されるか、ディレクトリーが存在しないことが示されます。次に、クライアントは RPC リクエスト LOOKUP を発行し、リクエストしたファイルが存在するかどうかを調べます。存在する場合には、そのファイルに対する RPC リクエスト GETATTR が発行され、それによってファイルの属性が返されます。GETATTR および LOOKUP が正常に完了した場合には、クライアントはファイル・ハンドルを作成します。ユーザーは、このファイル・ハンドルをその後のリクエストで使用することになります。

リモート・ファイルシステム内でファイルが特定されていれば、クライアントは RPC リクエスト READ を実行することができます。READ は読み取り操作のためのファイル・ハンドル、状態、オフセット、そしてカウントからなります。クライアントは状態を参照して操作を実行できるかどうか (つまり、ファイルがロックされているかどうか) を判別します。オフセットは読み取りを開始する位置を示し、カウントは読み取るバイト数を表します。サーバーはリクエストされたバイト数を返すことも、返さないこともありますが、RPC レスポンス READ の中には (データと併せて) サーバーが返すバイト数が示されます。

NFS における技術革新

最新の 2 つのバージョンのNFS (バージョン 4 および 4.1) は、NFS のバージョンのうちで最も興味深く、NFS にとって最も重要なバージョンです。ここからは、NFS の進化の中でも特に重要な点をいくつか取り上げます。

NFSv4 より前のバージョンでは、マウントやロック、そしてファイル管理におけるその他の要素を対象とした補助的なプロトコルが多数ありました。NFSv4 はこのプロセスを 1 つのプロトコルにまとめることで簡素化し、トランスポート・プロトコルとしての UDP のサポートを取りやめました。NFSv4 はまた、UNIX および Windows® ベースのファイル・アクセス動作のサポートを統合することによって、NFS を他のオペレーティング・システムにネイティブに統合できるように拡張します。

NFSv4.1 でスケーリング能力とパフォーマンスをより高めるために導入しているのは、pNFS (parallel NFS: パラレル NFS) の概念です。より高度なスケーリングをサポートするために、NFSv4.1 はクラスタリングされたファイルシステムと同じように、ストライピングによる分割データ/メタデータ・アーキテクチャーを実装します。図 4 を見るとわかるように、pNFS はエコシステムをクライアント、サーバー、ストレージの 3 つに分割します。図に示されているとおり、このアーキテクチャーには 2 つのパスがあります。1 つはデータ用のパス、もう 1 つは制御用のパスです。pNFS はデータのレイアウトをデータ自体から切り離すことで、デュアルパス・アーキテクチャーを可能にします。クライアントがファイルにアクセスする必要があるときには、サーバーはレイアウトを返します。レイアウトが記述するのはファイルとストレージ・デバイスとのマッピングです。そのためレイアウトを受け取ったクライアントは、サーバーを介すことなく直接ストレージにアクセスできるようになります (したがって、スケーリング能力とパフォーマンスが高くなります)。クライアントはファイルを使用し終わると、データ (変更) とレイアウトをコミットします。必要な場合には、サーバーがクライアントにレイアウトを戻すようにリクエストすることもできます。

pNFS はこの振る舞いをサポートするためにいくつもの新しいプロトコル操作を実装しています。例えば、LayoutGetLayoutReturn は、それぞれサーバーからレイアウトを取得、解放します。また、LayoutCommit はクライアントからストレージにデータをコミットして、他のユーザーがデータを使用できるようにします。サーバーがクライアントからレイアウトを回収するには、LayoutRecall を使用します。レイアウトは、並列アクセスおよびより高いパフォーマンスを実現するために複数のストレージ・デバイスにまで広がります。

図 4. NFSv4.1 の pNFS アーキテクチャー
NFSv4.1 の pNFS アーキテクチャー
NFSv4.1 の pNFS アーキテクチャー

データとメタデータはどちらもストレージ域に保管されます。レイアウトを受け取ったクライアントは直接 I/O を実行できる一方、NFSv4.1 サーバーがメタデータの管理と保管を行います。この振る舞いは必ずしも新しいものではありませんが、pNFS はそこに、ストレージに対する複数のアクセス・メソッドをサポートする機能を追加しています。現在、pNFS はブロック・ベースのプロトコル (Fibre Channel)、オブジェクト・ベースのプロトコル、そして (pNFS の形でないとしても) NFS 自体の使用をサポートします。

NFS での作業は継続中であり、2010年 9月には NFSv2 の要件が公開されました。新たな機能強化の一部は、仮想環境で変わりつつあるストレージの世界に対応するためのものです。例えば、ハイパーバイザー環境ではデータが重複している可能性が大いに考えられます (多くのオペレーティング・システムが同じデータの読み取り/書き込み、キャッシングを行うため)。そのため、ストレージ・システム全体としてどこで重複が生じているのかを把握することが望まれます。それによって、クライアント・サイドではキャッシュ・スペースが保たれ、ストレージ・サイドでは容量が保たれることになります。そこで NFSv4.2 で提案しているのが、共有ブロックからなるブロック・マップによってこの問題に対処するという方法です。現在、ストレージ・システムは処理能力をバックエンドに統合し始めるようになっています。このことから、サーバー・サイドのコピーを導入し、ストレージのバックエンド自体で効率的にデータ・コピーを処理できる場合には、内部ストレージ・ネットワークからデータ・コピーの負担を取り除くという仕組みです。この他にも、フラッシュ・メモリーを対象としたサブファイルのキャッシングや、I/O に対するクライアント・サイドのヒント (おそらく mapadvise をパスとして使用) などの技術革新が登場し始めています。

NFS に代わる手段

NFS は UNIX および Linux システムでは最もよく使用されているネットワーク・ファイルシステムですが、もちろん NFS だけが唯一の選択肢ではありません。Windows® システムで最も広く採用されているのは、SMB (Server Message Block: CIFS とも呼ばれています) です。ただし、Linux が SMB をサポートするように、Windows も NFS をサポートします。

最新の分散ファイルシステムの 1 つで、Linux でもサポートされているのは Ceph です。Ceph は、POSIX (Portable Operating System Interface for UNIX) との互換性を備えた耐障害性分散ファイルシステムとして一から設計されました。Ceph について詳しく学ぶには、「参考文献」を参照してください。

その他の例には、Andrew 分散ファイルシステムの (カーネギー・メロン大学および IBM による) オープンソース・バージョンである OpenAFS、スケーラブル・ストレージとしての汎用分散ファイルシステムに重点を置く GlusterFS、そしてクラスター・コンピューティングを焦点とした超並列分散ファイルシステム Lustre などがあります。このすべてが、分散ストレージに対処するオープンソースのソフトウェア・ソリューションです。

さらに詳しく調べてください

NFS は進化をつづけています。そして Linux の進化 (低価格、組み込み、高性能をサポートするための進化) と同じように、NFS は顧客と企業の両方に向けたスケーラブルなストレージ・ソリューションを実装します。NFS にこの先何が待ち受けているかは興味深い点ですが、その歴史と近い将来を見る限り、NFS はファイル・ストレージに対する見方とその使い方を変えていくことになるでしょう。


ダウンロード可能なリソース


関連トピック

  • NFS は、移植可能なマルチプラットフォーム対応のネットワーク・ファイルシステムのための標準仕様です。NFS は最初の仕様である NFSv2 から NFSv3NFSv4、そして最新の NFSv4.1 まで、数々の仕様で文書化されています。NFSv4.2 要件の文書で NFS の将来についても学ぶことができます。
  • YANFS (Yet Another NFS) は Sun のプロジェクトです (旧称 WebNFS)。YANFS は NFSv3 および RPC/XDR の Java™ 実装で、Java アプリケーションから NFS にアクセスできるようにします。
  • XDR は、多種多様なアーキテクチャーのホストが共通データ型を使用してネットワーク通信を行えるようにする標準エンコード方式です。
  • Linux は、多数のストレージ・メディアでの多種多様なファイルシステムをサポートします。Linux がこれを可能にしている手段は、多数のファイルシステム、各種ストレージ・ハードウェアのドライバー、そして VFS の統合です。VFS について詳しく学ぶには、「Linux ファイルシステムの徹底調査」(developerWorks、2007年10月) を読んでください。
  • ネットワーク・ストレージ・システムを構築する手段は、NFS だけではありません。NFS 以外にも、OpenAFSGlusterFSLustreCeph などを使用できます。Ceph については、「Ceph: Linux のペタバイト規模の分散ファイルシステム」(developerWorks、2010年5月) で詳しく説明しています。
  • developerWorks Linux ゾーンで、Linux 開発者および管理者向けのハウツー記事とチュートリアル、そしてダウンロード、ディスカッション、フォーラムなど、豊富に揃った資料を探してください。
  • Twitter で developerWorks をフォローするか、developerWorks で Linux に関するツイートのフィードに登録してください。
  • ご自分に最適な方法で IBM 製品を評価してください。評価の方法としては、製品の試用版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=594576
ArticleTitle=ネットワーク・ファイルシステムと Linux
publish-date=11102010