Hadoop 分散ファイルシステムの紹介

HDFS フレームワークおよびサブシステムの詳細を探る

Apache Hadoop プロジェクトのサブプロジェクトである HDFS (Hadoop Distributed File System) は、コモディティー化された低コストのハードウェア上で実行されるように設計された高度なフォルト・トレラント分散ファイルシステムです。アプリケーション・データへのアクセスにおいて高スループットを実現する HDFS は、大容量のデータ・セットを使用するアプリケーションに適しています。この記事では、HDFS の主要な機能を詳しく探るとともに、HDFS アーキテクチャーの概要を説明します。

J. Jeffrey Hanson, CTO, Max International

Jeff HansonJeff Hanson は、ソフトウェア・エンジニアおよびアーキテクトとして 20 年以上の経験を持っている、Max International の CTO です。彼は『Mashups: Strategies for the Modern Enterprise』など数多くの記事と本を執筆しています。



2011年 2月 01日

HDFS は Apache Software Foundation プロジェクトの一部であり、Apache Hadoop プロジェクトのサブプロジェクトとなっています (「参考文献」を参照)。テラバイトやペタバイトといった膨大な量のデータを保管するのに最適な Hadoop では、そのストレージ・システムとして HDFS を使用しています。HDFS では、データ・ファイルが分散されたクラスター内のさまざまなノード (一般的なパーソナル・コンピューター) に接続することができます。そして 1 つのシームレスなファイルシステムとして、データ・ファイルに対するアクセスおよび保管操作を行うことができます。データ・ファイルへのアクセスは、ストリーミング方式で処理されます。これは、MapReduce 処理モデル (同じく「参考文献」を参照) によってアプリケーションまたはコマンドが直接実行されることを意味します。

HDFS はフォルト・トレラントなシステムであり、大容量のデータ・セットへのアクセスにおいて高スループットを実現します。この記事では、HDFS の主要な機能を詳しく探り、HDFS アーキテクチャーの概要を説明します。

HDFS の概要

HDFS には、他の分散ファイルシステムと多くの類似点がありますが、いくつかの点で他とは一線を画します。その顕著な違いの 1 つは、書き込みは 1 回限りで読み取りは何度もできるという、HDFS の write-once-read-many モデルです。このアクセス・モデルは、並行性制御の要件を緩和し、データの一貫性に関する問題を単純化し、高スループットでのアクセスを可能にします。

さらに HDFS は他の分散ファイルシステムにはないユニークな視点を持っています。通常、HDFS ではデータをアプリケーション空間に移すよりも、処理ロジックをデータの近くに配置するほうが好ましいという見方をします。

HDFS では、データは 1 度に 1 つのライターに書き込まれるように厳格に制限されます。ストリームの最後には必ずバイトが追加され、バイト・ストリームは書き込まれた順で確実に保管されます。

HDFS には多数の目標があります。そのなかでも、特に注目に値する目標は以下のとおりです。

  • 障害を検出し、素早く自動リカバリーを適用することによるフォルト・トレランスの実現
  • MapReduce ストリーミングによるデータ・アクセスの実現
  • シンプルで堅牢な一貫性モデルの実現
  • データを処理ロジックの近くに移動するのではなく、処理ロジックをデータの近くに移動すること
  • コモディティー化された多種多様なハードウェアおよびオペレーティング・システムに移植できるようにすること
  • 大量のデータを確実に保管および処理するためのスケーラビリティーを実現すること
  • コモディティー化されたパーソナル・コンピューターからなるクラスターにデータを分散し、処理することで経済性を高めること
  • データとそれを処理するロジックを、データが配置される複数のノードに並列に分散して効率性を高めること
  • 信頼性を保つために、データの複数のコピーを自動的に保持し、障害発生時に処理ロジックを自動的に再デプロイすること

HDFS がアプリケーションに提供するインターフェースは、アプリケーションをデータの配置場所の近くに移せるようになっています。次のセクションでは、これらのインターフェースについて説明します。


HDFS とのアプリケーション・インターフェース

HDFS には、さまざまな手段でアクセスすることができます。例えば、HDFS はネイティブ Java™ API とネイティブ C 言語による Java API に対するラッパーを提供しています。さらに、Web ブラウザーを使用して HDFS ファイルをブラウズすることもできます。

その他、HDFS とのインターフェースを取る手段としては、表 1 に記載するアプリケーションを使用することもできます。

表 1. HDFS とインターフェースを取ることが可能なアプリケーション
アプリケーション説明
FS (FileSystem) シェル一般的な Linux® および UNIX® シェル (bash、csh など) と同様のコマンドライン・インターフェースです。このシェルを介して HDFS データを操作することができます。
DFSAdminHDFS クラスターを管理するために使用できるコマンド・セット。
fsckHadoop コマンド/アプリケーションのサブコマンド。fsck コマンドは、ブロックの欠落などといったファイルの不整合をチェックするために使用することができます。ただし、fsck コマンドを使用してこれらの不整合を修復することはできません。
名前ノードおよびデータ・ノードWeb サーバーに組み込まれたこれらのノードは、管理者がクラスターの現在の状態をチェックするために使用することができます。

HDFS には、大きな期待に応える類まれな機能セットが備わっています。それは、そのシンプルながらも強力なアーキテクチャーのおかげです。


HDFS のアーキテクチャー

HDFS は、相互に接続された複数のクラスターからなります。これらのクラスターを構成するのは、ファイルおよびディレクトリーが置かれたノードです。HDFS クラスターには、名前ノード (NameNode) と呼ばれる単一のノードがあります。このノードが、ファイルシステムの名前空間を管理し、ファイルに対するクライアントのアクセスを制限します。さらに、データをファイル内のブロックとして保管するデータ・ノード (DataNodes) もあります。

名前ノードおよびデータ・ノード

HDFS 内では、ある特定の名前ノードがファイルシステム名前空間での処理 (ファイルやディレクトリーを開く、閉じる、名前変更するなど) を管理します。また、データ・ブロックをデータ・ノードにマッピングするのも名前ノードの役目です。一方、データ・ノードは HDFS クライアントからの読み取り/書き込みのリクエストを処理するとともに、管理を行う名前ノードからの命令に応じて、データ・ブロックを作成、削除、複製します。

図 1 に、HDFS アーキテクチャーの概要を示します。

図 1. HDFS アーキテクチャー
HDFS アーキテクチャーを示す図

図 1 に示されているように、クラスターごとに 1 つの名前ノードが含まれます。この設計によって、それぞれの名前空間を管理してデータ分散の調停をするためのモデルが簡潔なものになっています。

名前ノードとデータ・ノードとの関係

名前ノードとデータ・ノードは、一般的なマシン上に分散された形でさまざまなオペレーティング・システムで実行できるように設計されたソフトウェア・コンポーネントです。HDFS は Java プログラミング言語で構築されているため、Java をサポートするマシンであれば、HDFS を実行することができます。標準的なインストール・クラスターには、名前ノードと、おそらく 1 つのデータ・ノードだけを実行する専用のマシンがあります。クラスター内の他のマシンのそれぞれが 1 つのデータ・ノードを実行します。

通信プロトコル

HDFS 通信プロトコルはすべて共通して、TCP/IP プロトコルをベースに作成されています。HDFS クライアントは、名前ノード上でオープンしている TCP (Transmission Control Protocol) ポートに接続し、RPC (Remote Procedure Call) ベースの独自仕様のプロトコルを使って名前ノードと通信します。データ・ノードが名前ノードとやりとりするために使用するプロトコルは、ブロック・ベースの専用プロトコルです。

データ・ノードは継続的なループ処理によって、名前ノードに対して命令を発行するよう要求します。名前ノードがデータ・ノードに直接接続することはできません。名前ノードは、データ・ノードによって呼び出された関数の値を返すだけです。各データ・ノードは、クライアントのコードや他のデータ・ノードがデータを読み取ったり、書き込んだりできるように、サーバー・ソケットをオープンしたままにします。名前ノードは、このサーバー・ソケットのホストやポートについては認識しており、こうした情報を関連するクライアントや他のデータ・ノードに提供します。データ・ノード、名前ノード、およびクライアントとの間の通信についての詳細は、囲み記事「通信プロトコル」を参照してください。

名前ノードは、ファイルシステムの名前空間に対する変更を保守および管理します。

ファイルシステムの名前空間

HDFS は、ユーザーまたはアプリケーションがディレクトリーを作成したり、ファイルを保管したりできる、従来の階層型ファイル構成をサポートします。ファイルシステムの名前空間階層は、多くの他の既存のファイルシステムと類似しており、ユーザーがファイルの作成、名前変更、再配置、削除を行うことができます。

HDFS は、CloudStore や Amazon S3 (Simple Storage Service) などのサードパーティーのファイルシステムもサポートします (「参考文献」を参照)。


データ・レプリケーション

HDFS は、フォルト・トレランスを実現するためにファイル・ブロックを複製します。アプリケーションはファイルの作成時に、ファイルのレプリカ (複製) の数を指定することができます。この数は、後でいつでも変更することができます。ブロックのレプリケーションに関するすべての決定は、名前ノードが行います。

ラックの認識

一般に、大規模な HDFS クラスターは複数のラック (コンピューターのインストール環境) にまたがって配置されます。同じラック内にある異なるノード間のネットワーク・トラフィックは、異なるラックに属するノード間のネットワーク・トラフィックよりも効率的です。名前ノードは、フォルト・トレランスの能力を向上させるために、複数のラックにブロックのレプリカを配置しようとしますが、ノードが属するラックは、HDFS では管理者が決定できるようになっています。したがって、各ノードにはそのラック ID が通知されて、ラックを認識するというわけです。

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 ハートビート

さまざまな原因で名前ノードとデータ・ノードとの間の接続が失われる可能性があるため、各データ・ノードは定期的に、名前ノードにハードビート・メッセージを送信します。名前ノードがハートビート・メッセージを受信しなくなると、それによって接続断を検出するという仕組みです。名前ノードは、ハートビート・メッセージを送信してこなくなったデータ・ノードに不通データ・ノードとして認識し、そのデータ・ノードには以降のリクエストを送信しません。HDFS クライアントは、不通データ・ノードからは、そこに保管されているデータを入手できないため、不通データ・ノードは実質的にシステムから除外されます。ノードの不通によって、データ・ブロックのレプリケーション因子が最小値を下回った場合、名前ノードは追加のレプリケーションを開始して、レプリケーション因子を通常の状態に戻します。

図 2 に、HDFS のハードビート・メッセージ送信プロセスを説明します。

図 2. HDFS のハートビート・プロセス
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 との統合に関する資料も用意されています。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=629708
ArticleTitle=Hadoop 分散ファイルシステムの紹介
publish-date=02012011