HDFS は Apache Software Foundation プロジェクトの一部であり、Apache Hadoop プロジェクトのサブプロジェクトとなっています (「参考文献」を参照)。テラバイトやペタバイトといった膨大な量のデータを保管するのに最適な Hadoop では、そのストレージ・システムとして HDFS を使用しています。HDFS では、データ・ファイルが分散されたクラスター内のさまざまなノード (一般的なパーソナル・コンピューター) に接続することができます。そして 1 つのシームレスなファイルシステムとして、データ・ファイルに対するアクセスおよび保管操作を行うことができます。データ・ファイルへのアクセスは、ストリーミング方式で処理されます。これは、MapReduce 処理モデル (同じく「参考文献」を参照) によってアプリケーションまたはコマンドが直接実行されることを意味します。
HDFS はフォルト・トレラントなシステムであり、大容量のデータ・セットへのアクセスにおいて高スループットを実現します。この記事では、HDFS の主要な機能を詳しく探り、HDFS アーキテクチャーの概要を説明します。
HDFS には、他の分散ファイルシステムと多くの類似点がありますが、いくつかの点で他とは一線を画します。その顕著な違いの 1 つは、書き込みは 1 回限りで読み取りは何度もできるという、HDFS の write-once-read-many モデルです。このアクセス・モデルは、並行性制御の要件を緩和し、データの一貫性に関する問題を単純化し、高スループットでのアクセスを可能にします。
さらに HDFS は他の分散ファイルシステムにはないユニークな視点を持っています。通常、HDFS ではデータをアプリケーション空間に移すよりも、処理ロジックをデータの近くに配置するほうが好ましいという見方をします。
HDFS では、データは 1 度に 1 つのライターに書き込まれるように厳格に制限されます。ストリームの最後には必ずバイトが追加され、バイト・ストリームは書き込まれた順で確実に保管されます。
HDFS には多数の目標があります。そのなかでも、特に注目に値する目標は以下のとおりです。
- 障害を検出し、素早く自動リカバリーを適用することによるフォルト・トレランスの実現
- MapReduce ストリーミングによるデータ・アクセスの実現
- シンプルで堅牢な一貫性モデルの実現
- データを処理ロジックの近くに移動するのではなく、処理ロジックをデータの近くに移動すること
- コモディティー化された多種多様なハードウェアおよびオペレーティング・システムに移植できるようにすること
- 大量のデータを確実に保管および処理するためのスケーラビリティーを実現すること
- コモディティー化されたパーソナル・コンピューターからなるクラスターにデータを分散し、処理することで経済性を高めること
- データとそれを処理するロジックを、データが配置される複数のノードに並列に分散して効率性を高めること
- 信頼性を保つために、データの複数のコピーを自動的に保持し、障害発生時に処理ロジックを自動的に再デプロイすること
HDFS がアプリケーションに提供するインターフェースは、アプリケーションをデータの配置場所の近くに移せるようになっています。次のセクションでは、これらのインターフェースについて説明します。
HDFS には、さまざまな手段でアクセスすることができます。例えば、HDFS はネイティブ Java™ API とネイティブ C 言語による Java API に対するラッパーを提供しています。さらに、Web ブラウザーを使用して HDFS ファイルをブラウズすることもできます。
その他、HDFS とのインターフェースを取る手段としては、表 1 に記載するアプリケーションを使用することもできます。
表 1. HDFS とインターフェースを取ることが可能なアプリケーション
アプリケーション | 説明 |
---|---|
FS (FileSystem) シェル | 一般的な Linux® および UNIX® シェル (bash、csh など) と同様のコマンドライン・インターフェースです。このシェルを介して HDFS データを操作することができます。 |
DFSAdmin | HDFS クラスターを管理するために使用できるコマンド・セット。 |
fsck | Hadoop コマンド/アプリケーションのサブコマンド。fsck コマンドは、ブロックの欠落などといったファイルの不整合をチェックするために使用することができます。ただし、fsck コマンドを使用してこれらの不整合を修復することはできません。 |
名前ノードおよびデータ・ノード | Web サーバーに組み込まれたこれらのノードは、管理者がクラスターの現在の状態をチェックするために使用することができます。 |
HDFS には、大きな期待に応える類まれな機能セットが備わっています。それは、そのシンプルながらも強力なアーキテクチャーのおかげです。
HDFS は、相互に接続された複数のクラスターからなります。これらのクラスターを構成するのは、ファイルおよびディレクトリーが置かれたノードです。HDFS クラスターには、名前ノード (NameNode
) と呼ばれる単一のノードがあります。このノードが、ファイルシステムの名前空間を管理し、ファイルに対するクライアントのアクセスを制限します。さらに、データをファイル内のブロックとして保管するデータ・ノード (DataNodes
) もあります。
HDFS 内では、ある特定の名前ノードがファイルシステム名前空間での処理 (ファイルやディレクトリーを開く、閉じる、名前変更するなど) を管理します。また、データ・ブロックをデータ・ノードにマッピングするのも名前ノードの役目です。一方、データ・ノードは HDFS クライアントからの読み取り/書き込みのリクエストを処理するとともに、管理を行う名前ノードからの命令に応じて、データ・ブロックを作成、削除、複製します。
図 1 に、HDFS アーキテクチャーの概要を示します。
図 1. HDFS アーキテクチャー
図 1 に示されているように、クラスターごとに 1 つの名前ノードが含まれます。この設計によって、それぞれの名前空間を管理してデータ分散の調停をするためのモデルが簡潔なものになっています。
名前ノードとデータ・ノードは、一般的なマシン上に分散された形でさまざまなオペレーティング・システムで実行できるように設計されたソフトウェア・コンポーネントです。HDFS は Java プログラミング言語で構築されているため、Java をサポートするマシンであれば、HDFS を実行することができます。標準的なインストール・クラスターには、名前ノードと、おそらく 1 つのデータ・ノードだけを実行する専用のマシンがあります。クラスター内の他のマシンのそれぞれが 1 つのデータ・ノードを実行します。
データ・ノードは継続的なループ処理によって、名前ノードに対して命令を発行するよう要求します。名前ノードがデータ・ノードに直接接続することはできません。名前ノードは、データ・ノードによって呼び出された関数の値を返すだけです。各データ・ノードは、クライアントのコードや他のデータ・ノードがデータを読み取ったり、書き込んだりできるように、サーバー・ソケットをオープンしたままにします。名前ノードは、このサーバー・ソケットのホストやポートについては認識しており、こうした情報を関連するクライアントや他のデータ・ノードに提供します。データ・ノード、名前ノード、およびクライアントとの間の通信についての詳細は、囲み記事「通信プロトコル」を参照してください。
名前ノードは、ファイルシステムの名前空間に対する変更を保守および管理します。
HDFS は、ユーザーまたはアプリケーションがディレクトリーを作成したり、ファイルを保管したりできる、従来の階層型ファイル構成をサポートします。ファイルシステムの名前空間階層は、多くの他の既存のファイルシステムと類似しており、ユーザーがファイルの作成、名前変更、再配置、削除を行うことができます。
HDFS は、CloudStore や Amazon S3 (Simple Storage Service) などのサードパーティーのファイルシステムもサポートします (「参考文献」を参照)。
HDFS は、フォルト・トレランスを実現するためにファイル・ブロックを複製します。アプリケーションはファイルの作成時に、ファイルのレプリカ (複製) の数を指定することができます。この数は、後でいつでも変更することができます。ブロックのレプリケーションに関するすべての決定は、名前ノードが行います。
HDFS は信頼性とパフォーマンスのために、インテリジェントなレプリカ配置モデルを使用します。レプリカの配置を最適化する HDFS は、他の多くの分散ファイルシステムとは一線を画しています。この最適化を容易にするのが、ネットワーク帯域幅を効率的に使用する、ラック認識レプリカ配置ポリシーです。
大規模な HDFS 環境は、一般に、複数のラック (コンピューター・インストール環境) で動作します。それぞれに異なるラック内にある 2 つのデータ・ノード間の通信には、同じラック内にあるデータ・ノード間の通信よりも時間がかかるのが通常です。そのことから、名前ノードはデータ・ノード間の通信を最適化する手段として、データ・ノードのロケーションをそれぞれのラック ID によって識別します。
HDFS の主な目標の 1 つは、大きなサイズのファイルをサポートすることです。標準的な HDFS ブロックのサイズは 64MB であるため、各 HDFS ファイルを構成するのは 1 つ以上の 64MB のブロックということになります。HDFS では、これらのブロックのそれぞれを、個別のデータ・ノードに配置するようにしています。
HDFS でファイルを操作するプロセスは、他のファイルシステムで使用されているプロセスと同様です。ただし、HDFS は複数のマシンが単一のディスクとして表現されたシステムであることから、HDFS 上でファイルを操作するコードはすべて、org.apache.hadoop.fs.FileSystem
オブジェクトのサブクラスを使用します (「参考文献」を参照)。
リスト 1 のコードに、HDFS での一般的なファイル作成プロセスを説明します。
リスト 1. HDFS での一般的なファイル作成プロセス
byte[] fileData = retrieveFileDataFromSomewhere(); String filePath = retrieveFilePathStringFromSomewhere(); Configuration config = new Configuration(); // assumes to automatically load // hadoop-default.xml and hadoop-site.xml org.apache.hadoop.fs.FileSystem hdfs = org.apache.hadoop.fs.FileSystem.get(config); org.apache.hadoop.fs.Path path = new org.apache.hadoop.fs.Path(filePath); org.apache.hadoop.fs.FSDataOutputStream outputStream = hdfs.create(path); outputStream.write(fileData, 0, fileData.length); |
クライアントが HDFS 内にファイルを作成すると、そのデータは一時ローカル・ファイルにキャッシュされ、以降の書き込み操作は、この一時ファイルにリダイレクトされます。HDFS ブロックのサイズに相当するデータが一時ファイルに蓄積された時点で、クライアントはこのことを名前ノードに報告します。すると、名前ノードは一時ファイルを恒久的なデータ・ノードに変換します。クライアントは一時ファイルを閉じ、残りのすべてのデータを新しく作成されたデータ・ノードにフラッシュします。その後、名前ノードはデータ・ノードをディスクにコミットします。
クライアントがブロックを満たすだけのユーザー・データを蓄積すると、そのブロックのレプリカが含まれるデータ・ノードのリストを名前ノードから取得します。クライアントは、取得したレプリカ・リストに指定された最初のデータ・ノードに、フルになったデータ・ブロックをフラッシュします。データのチャンクを受け取ったデータ・ノードは、それをディスクに書き込み、そのコピーをリスト内の次のデータ・ノードに転送します。次のデータも、これと同じ処理を行います。このパイプライン・プロセスは、レプリケーション因子が満たされるまで繰り返されます。
HDFS の重要な目標の 1 つは、名前ノードやデータ・ノード、あるいはネットワーク・パーティションで障害が発生したとしても、データが確実に保管されるようにすることです。
HDFS が障害を克服するための最初のステップとしているのは、障害の検出です。HDFS はハートビート・メッセージを使用して、名前ノードとデータ・ノードとの接続性を検出します。
さまざまな原因で名前ノードとデータ・ノードとの間の接続が失われる可能性があるため、各データ・ノードは定期的に、名前ノードにハードビート・メッセージを送信します。名前ノードがハートビート・メッセージを受信しなくなると、それによって接続断を検出するという仕組みです。名前ノードは、ハートビート・メッセージを送信してこなくなったデータ・ノードに不通データ・ノードとして認識し、そのデータ・ノードには以降のリクエストを送信しません。HDFS クライアントは、不通データ・ノードからは、そこに保管されているデータを入手できないため、不通データ・ノードは実質的にシステムから除外されます。ノードの不通によって、データ・ブロックのレプリケーション因子が最小値を下回った場合、名前ノードは追加のレプリケーションを開始して、レプリケーション因子を通常の状態に戻します。
図 2 に、HDFS のハードビート・メッセージ送信プロセスを説明します。
図 2. HDFS のハートビート・プロセス
HDFS データ・ブロックは、常に均一にデータ・ノードに配置されるわけではありません。これは、1 つ以上のデータ・ノード用のスペースが十分に活用されない可能性があることを意味します。そのことから、HDFS はさまざまなモデルを使用して、データ・ブロックの再バランシングをサポートします。モデルの一例は、データ・ノード上の空きスペースが小さくなり過ぎた場合、データ・ブロックをそのデータ・ノードから別のノードに自動的に移すというものです。また、特定のファイルの需要が急激に高くなった場合には動的に追加のレプリカを作成し、クラスター内の他のデータ・ブロックを再バランシングするというモデルもあります。また、HDFS には、手動で再バランシング・タスクを行えるように hadoop balance
コマンドも用意されています。
再バランシングの必要が生じる一般的な理由の 1 つは、クラスターに新しいデータ・ノードが追加されたことによります。新しいブロックを配置する際に、名前ノードは各種のパラメーターを検討してから、これらのパラメーターを受け取るデータ・ノードを選択します。例えば、以下のパラメーターが検討されます。
- ブロック・レプリカの書き込みポリシー
- インストールまたはラック障害によるデータ損失の防止
- 異なるラック間でのネットワーク I/O の削減
- クラスター内データ・ノードでの均一なデータ分散
HDFS のクラスター再バランシング機能は、データの完全性を維持するために HDFS が使用するメカニズムの 1 つでしかありません。次のセクションでは、これ以外のメカニズムについて説明します。
HDFS はクラスター間でのデータの完全性を確実にするために、あらゆる対策をとっています。HDFS ファイルの内容に対して行うのは、チェックサム検証です。計算されたチェックサムは、実際のデータと同じ名前空間にある別の隠しファイルに保管されるので、ファイル・データを受け取ったクライアントは、関連ファイルに保管されたチェックサムと突き合わせることで、受信したデータを検証することができます。
HDFS 名前空間は、それぞれの名前ノードが保持するトランザクション・ログを使って保管されます。ファイルシステムの名前空間は、ブロック・マッピングおよびファイルシステム・プロパティーと一緒に FsImage というファイルに保管されます。名前ノードの初期化時には、他のファイルと併せて FsImage ファイルが読み取られ、これらのファイルで見つかったトランザクションおよび状態情報が適用されます。
名前ノードは、EditLog として知られるログ・ファイルを使用して、HDFS ファイルシステムのメタデータに対して行われるすべてのトランザクションを永続的に記録します。EditLog または FsImage ファイルが破損すると、そのファイルが属する HDFS インスタンスは機能を停止します。したがって、名前ノードは FsImage および EditLog ファイルの複数のコピーを保持できるようになっています。複数のファイル・コピーを保持する場合、いずれかのファイルに対する変更は、すべてのコピーに同期的に伝播されます。名前ノードが再起動すると、名前ノードは整合性のとれた最新バージョンの FsImage および EditLog を使用して自らを初期化します。
ユーザー、ファイル、およびディレクトリーに対する HDFS パーミッション
HDFS は、ファイルとディレクトリーに対するパーミッション・モデルを実装します。このモデルは、POSIX (Portable Operating System Interface) モデルとかなり共通しており、例えば、すべてのファイルおよびディレクトリーは、所有者とグループに関連付けられます。HDFS のパーミッション・モデルは、読み取り (r)、書き込み (r)、実行 (x) をサポートします。HDFS にはファイル実行の概念が含まれていないため、x パーミッションは別の意味を持ちます。簡単に言うと、x 属性は、特定の親ディレクトリーの子ディレクトリーへのアクセスを許可します。ファイルまたはディレクトリーの所有者は、そのファイルまたはディレクトリーを作成したクライアント・プロセスの ID となります。グループとは、親ディレクトリーのグループのことです。
HDFS は当初、スナップショットを使用して、破損した HDFS インスタンスを以前の状態にロールバックできるようにする予定となっていました。けれども今のところ、HDFS のスナップショット・サポートは見送られています。
Hadoop は、大容量のデータを保管および管理することを目標としたApache Software Foundation の分散ファイルシステム兼データ管理プロジェクトです。Hadoop はそのストレージ・システムとして HDFS を使用して、データ・ブロックが分散されたクラスター内の一般的なパーソナル・コンピューター (ノード) に接続します。そして MapReduce 処理モデルにより、1 つのシームレスなファイルシステムとしてのデータ・ブロックにアクセスし、データ・ブロックを保管することができます。
HDFS には、他の分散ファイルシステムと共通する機能も数多くありますが、他のファイルシステムとは一線を画す重要な違いがあります。その顕著な違いの 1 つは、書き込みは 1 回限りで読み取りは何度もできるという、HDFS の write-once-read-many モデルです。このアクセス・モデルは、並行性制御の要件を緩和し、データの一貫性に関する問題を単純化し、高スループットのアクセスを実現します。
最適化されたデータ・アクセス・モデルを提供するために、HDFS はデータをアプリケーション空間の近くに配置するのではなく、処理ロジックをデータの近くに配置するように設計されています。
学ぶために
- Hadoop Wiki に、Hadoop および HDFS に関するコミュニティーの情報が提供されています。
- Hadoop API サイトで、Hadoop および HDFS をプログラミングするために使用する Java クラスおよびインターフェースについて説明しています。
- ウィキペディアの MapReduce ページは、MapReduce フレームワークについて詳しく調べる際に絶好の出発点となります。
- Amazon S3 にアクセスして、Amazon の S3 インフラストラクチャーについて学んでください。
- developerWorks Web development ゾーンでは、多種多様な Web ベースのソリューションを話題にした記事を揃えています。
製品や技術を入手するために
- Hadoop プロジェクトのサイトには、Hadoop アーキテクチャーおよび MapReduce フレームワークに関する貴重なリソースが揃っています。
- Hadoop Distributed File System プロジェクトのサイトから、HDFS のダウンロードおよび資料を入手できます。
- CloudStore サイトにアクセスして、CloudStore をダウンロードしてください。また、このサイトには CloudStore、Hadoop、HDFS との統合に関する資料も用意されています。
0 件のコメント:
コメントを投稿