HDFS チュートリアル: ArchiJava APIを使用した読み取りおよび書き込み操作の構造

HDFSとは何ですか?

HDFS は、非常に大きなデータ ファイルを保存するための分散ファイル システムであり、汎用ハードウェアのクラスタ上で実行されます。 耐障害性があり、スケーラブルであり、拡張が非常に簡単です。 Hadoop にはバンドルされています HDFS (Hadoop分散ファイルシステム).

データが XNUMX 台の物理マシン上のストレージ容量を超えると、データを複数の個別のマシンに分割することが不可欠になります。 マシンのネットワーク全体でストレージ固有の操作を管理するファイル システムは、分散ファイル システムと呼ばれます。 HDFS もそのようなソフトウェアの XNUMX つです。

HDFS Archi構造

HDFS クラスターは主に、 ネームノード ファイルシステムを管理するもの フォルダーとその下に データノード それを保存するのは 実際のデータ.

  • NameNode: NameNode はシステムのマスターとみなすことができます。 ファイル システム ツリーと、システム内に存在するすべてのファイルとディレクトリのメタデータを維持します。 XNUMXつのファイル 「名前空間イメージ」「編集ログ」 メタデータ情報を保存するために使用されます。 Namenode は、特定のファイルのデータ ブロックを含むすべてのデータノードについての知識を持っていますが、ブロックの場所を永続的に保存しません。 この情報は、システムの起動時にデータノードから毎回再構築されます。
  • DataNode: DataNode はクラスター内の各マシンに常駐し、実際のストレージを提供するスレーブです。 クライアントに対する読み取りおよび書き込みリクエストの処理を担当します。

HDFS での読み取り/書き込み操作はブロック レベルで動作します。 HDFS 内のデータ ファイルはブロック サイズのチャンクに分割され、独立した単位として保存されます。 デフォルトのブロックサイズは 64 MB です。

HDFS はデータ レプリケーションの概念に基づいて動作し、データ ブロックの複数のレプリカが作成され、クラスター全体のノードに分散されることで、ノード障害時のデータの高可用性が可能になります。

あなたは知っていますか? HDFS 内のファイルは単一ブロックより小さいため、ブロックのストレージ全体を占有することはありません。

HDFS での読み取り操作

データ読み取りリクエストは、HDFS、NameNode、および DataNode によって処理されます。 読者を「クライアント」と呼びます。 以下の図は、ファイル読み取り操作を示しています。 Hadoopの.

HDFS での読み取り操作

  1. クライアントは呼び出して読み取りリクエストを開始します。 '開ける()' FileSystem オブジェクトのメソッド。 それは型のオブジェクトです 分散ファイルシステム.
  2. このオブジェクトは、RPC を使用して namenode に接続し、ファイルのブロックの場所などのメタデータ情報を取得します。 これらのアドレスはファイルの最初の数ブロックのものであることに注意してください。
  3. このメタデータ要求に応答して、そのブロックのコピーを持つデータノードのアドレスが返されます。
  4. DataNode のアドレスを受信すると、次のタイプのオブジェクトが返されます。 FSDataInputStream クライアントに返されます。 FSDataInputStream 含まれています DFS入力ストリーム これは、DataNode および NameNode との対話を処理します。 上の図に示すステップ 4 では、クライアントが次のコマンドを呼び出します。 '読む()' 原因となる方法 DFS入力ストリーム ファイルの最初のブロックを使用して最初の DataNode との接続を確立します。
  5. データは、クライアントが呼び出すストリームの形式で読み取られます。 '読む()' メソッドを繰り返します。 このプロセスの 読んだ() 操作はブロックの終わりに達するまで続きます。
  6. ブロックの終わりに到達すると、DFSInputStream は接続を閉じ、次のブロックの次の DataNode の検索に進みます。
  7. クライアントが読み取りを完了すると、呼び出します。 close() 方法。

HDFS での書き込み操作

このセクションでは、ファイルを通じてデータがどのように HDFS に書き込まれるかを理解します。

HDFS での書き込み操作

  1. クライアントは、新しいファイルを作成する DistributedFileSystem オブジェクトの 'create()' メソッドを呼び出して書き込み操作を開始します – ステップ 1。 上図のXNUMXです。
  2. DistributedFileSystem オブジェクトは、RPC 呼び出しを使用して NameNode に接続し、新しいファイルの作成を開始します。 ただし、このファイル作成操作では、ブロックがファイルに関連付けられません。 ファイル (作成中の) がまだ存在しないこと、およびクライアントが新しいファイルを作成するための正しいアクセス許可を持っていることを確認するのは、NameNode の責任です。 ファイルがすでに存在する場合、またはクライアントに新しいファイルを作成するための十分な権限がない場合は、 IO例外 クライアントに投げられます。他のwiseの場合、操作は成功し、NameNode によってファイルの新しいレコードが作成されます。
  3. NameNode に新しいレコードが作成されると、FSDataOutputStream 型のオブジェクトがクライアントに返されます。 クライアントはこれを使用して、HDFS にデータを書き込みます。 データ書き込みメソッドが呼び出されます (図のステップ 3)。
  4. FSDataOutputStream には、DataNode および NameNode との通信を管理する DFSOutputStream オブジェクトが含まれています。 クライアントがデータの書き込みを続けている間、 DFS出力ストリーム は、このデータを使用してパケットの作成を続けます。 これらのパケットは、次のように呼ばれるキューに入れられます。 データキュー.
  5. というコンポーネントがもう XNUMX つあります。 データストリーマー これを消費するのは データキュー。 DataStreamer はまた、NameNode に新しいブロックの割り当てを要求し、それによってレプリケーションに使用する望ましい DataNode を選択します。
  6. ここで、レプリケーションのプロセスは、DataNode を使用してパイプラインを作成することから始まります。 この例では、レプリケーション レベル 3 を選択したため、パイプラインには 3 つのデータノードがあります。
  7. DataStreamer は、パイプラインの最初の DataNode にパケットを注ぎます。
  8. パイプライン内のすべての DataNode は、受信したパケットを保存し、同じパケットをパイプライン内の XNUMX 番目の DataNode に転送します。
  9. 別のキュー「Ack Queue」は、DataNode からの確認応答を待っているパケットを格納するために DFSOutputStream によって維持されます。
  10. キュー内のパケットに対する確認応答がパイプライン内のすべてのデータノードから受信されると、そのパケットは「Ack キュー」から削除されます。 DataNode に障害が発生した場合、このキューからのパケットを使用して操作が再開されます。
  11. クライアントはデータの書き込みが完了すると、close() メソッドを呼び出します (図のステップ 9)。 close() を呼び出すと、残りのデータ パケットがパイプラインにフラッシュされ、その後確認応答を待ちます。
  12. 最終確認応答が受信されると、NameNode に連絡して、ファイル書き込み操作が完了したことを伝えます。

JAVA APIを使用してHDFSにアクセスする

このセクションでは、次のことを理解しようとします Java Hadoop のファイル システムにアクセスするために使用されるインターフェイス。

Hadoop のファイル システムをプログラムで操作するために、Hadoop は複数の JAVA クラスを提供します。 org.apache.hadoop.fs という名前のパッケージには、Hadoop のファイルシステム内のファイルの操作に役立つクラスが含まれています。 これらの操作には、オープン、読み取り、書き込み、クローズが含まれます。 実際、Hadoop のファイル API は汎用であり、HDFS 以外のファイルシステムと対話するように拡張できます。

プログラムによる HDFS からのファイルの読み取り

オブジェクトjava.net.URL ファイルの内容を読み取るために使用されます。 まず、Java に Hadoop の hdfs URL スキームを認識させる必要があります。 これは呼び出しによって行われます setURLStreamHandlerFactory URL オブジェクトのメソッドと FsUrlStreamHandlerFactory のインスタンスがそれに渡されます。 このメソッドは、XNUMX 回につき XNUMX 回だけ実行する必要があります。 JVMしたがって、静的ブロックで囲まれています。

コード例は次のとおりです-

public class URLCat {
    static {
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }
    public static void main(String[] args) throws Exception {
        InputStream in = null;
        try {
            in = new URL(args[0]).openStream();
            IOUtils.copyBytes(in, System.out, 4096, false);
        } finally {
            IOUtils.closeStream(in);
        }
    }
}

このコードは、ファイルを開いて内容を読み取ります。 HDFS 上のこのファイルのパスは、コマンド ライン引数としてプログラムに渡されます。

コマンドラインインターフェイスを使用して HDFS にアクセスする

これは、HDFS と対話する最も簡単な方法の XNUMX つです。 コマンドライン インターフェイスは、ファイルの読み取り、ディレクトリの作成、ファイルの移動、データの削除、ディレクトリの一覧表示などのファイル システム操作をサポートします。

走れる 「$HADOOP_HOME/bin/hdfs dfs -help」 すべてのコマンドに関する詳細なヘルプを表示します。 ここ、 「DFS」 は、複数のサブコマンドをサポートする HDFS のシェル コマンドです。

広く使用されているコマンドの一部と、いくつかのコマンドを以下に示します。tails それぞれの。

1. ローカル ファイル システムから HDFS にファイルをコピーします。

$HADOOP_HOME/bin/hdfs dfs -copyFromLocal temp.txt /

コマンドラインインターフェイスを使用して HDFS にアクセスする

このコマンドは、ファイル temp.txt をローカル ファイル システムから HDFS にコピーします。

2. 次を使用して、ディレクトリ内に存在するファイルを一覧表示できます。 -ls

$HADOOP_HOME/bin/hdfs dfs -ls /

コマンドラインインターフェイスを使用して HDFS にアクセスする

ファイルが見えます 「一時.txt」 (以前にコピーしました) の下にリストされています '/' ディレクトリにあります。

3. HDFS からローカル ファイルシステムにファイルをコピーするコマンド

$HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt

コマンドラインインターフェイスを使用して HDFS にアクセスする

見える 一時テキスト ローカル ファイルシステムにコピーされます。

4. 新しいディレクトリを作成するコマンド

$HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory

コマンドラインインターフェイスを使用して HDFS にアクセスする

ディレクトリが作成されているかどうかを確認します。 さて、あなたはそれを行う方法を知っているはずです 😉