10

サイズが 200 ~ 500 MB の (分割不可の) 何千もの gzip ファイルのシーケンシャル スキャンを実行する必要がある場合、これらのファイルの適切なブロック サイズはどれくらいですか?

この質問のために、実行される処理が非常に高速であるとしましょう。そのため、大きなブロック サイズであっても、マッパーを再起動してもコストはかかりません。

私の理解は次のとおりです。

  1. 私のクラスターのサイズに適した量のマッパーには「たくさんのファイル」があるため、ブロックサイズの上限はほとんどありません。
  2. データの局所性を確保するために、各 gzip ファイルを 1 つのブロックに収めたいと考えています。

ただし、gzip 圧縮されたファイルのサイズはさまざまです。~500mb のブロック サイズ (すべての入力ファイルの最大ファイル サイズなど) を選択した場合、データはどのように保存されますか? 2GB のような「非常に大きな」ブロック サイズを選択する方がよいでしょうか? どちらのシナリオでも、HDD 容量が過剰に浪費されていますか?

私は、ファイルが実際にどのように保存され、hdfs ブロック間で分割されるかを本当に尋ねていると思います-また、分割できないファイルのベストプラクティスを理解しようとしています。

更新: 具体例

次の図のように保存された 3 つの 200 MB ファイルに対して MR ジョブを実行しているとします。

ケース A のように HDFS がファイルを格納する場合、3 つのマッパーがそれぞれ「ローカル」ファイルを処理できることが保証されます。ただし、ファイルがケース B のように保存されている場合、1 つのマッパーが別のデータ ノードからファイル 2 の一部をフェッチする必要があります。

空きブロックがたくさんある場合、HDFS はケース A またはケース B のようにファイルを保存しますか?

HDFS 戦略

4

2 に答える 2

4

分割できないファイルがある場合は、より大きなブロック サイズを使用することをお勧めします。つまり、ファイル自体と同じ大きさ (またはそれより大きくても違いはありません)。

ブロック サイズが全体のファイル サイズよりも小さい場合、すべてのブロックが同じデータ ノード上にない可能性があり、データの局所性が失われます。ブロックごとにマップ タスクが作成されるため、これは分割可能なファイルでは問題になりません。

ブロック サイズの上限については、特定の古いバージョンの Hadoop では制限が 2GB であったことを知っています (これを超えるとブロックの内容を取得できませんでした) - https://issues.apache.org/jira/browse/HDFS-を参照してください。 96

小さいファイルを大きなブロック サイズで保存することのマイナス面はありません。この点を強調するために、それぞれブロック サイズが 2 GB の 1 MB と 2 GB のファイルを考えてみましょう。

  • 1 MB - 1 ブロック、ネーム ノードの単一エントリ、各データ ノード レプリカに物理的に格納される 1 MB
  • 2 GB - 1 ブロック、名前ノードの単一エントリ、各データ ノード レプリカに物理的に格納された 2 GB

そのため、必要な物理ストレージを除けば、名前ノード ブロック テーブルにマイナス面はありません (両方のファイルがブロック テーブルに 1 つのエントリを持っています)。

考えられる唯一の欠点は、小さいブロックと大きいブロックを複製するのにかかる時間ですが、反対に、データ ノードがクラスターから失われた場合、2000 x 1 MB ブロックを複製するタスクは、単一のブロック 2 GB ブロックよりも遅くなります。 .

更新 - 実際の例

これが混乱を引き起こしているのを見て、いくつかの実際の例を以下に示します。

HDFS ブロック サイズが 300 MB のシステムがあり、簡単にするために、データ ノードが 1 つだけの疑似クラスターがあるとします。

1100 MB のファイルを保存する場合、HDFS はそのファイルを最大300 MB のブロックに分割し、データ ノードの特別なブロック インデックス ファイルに保存します。データ ノードに移動して、インデックス付きブロック ファイルが物理ディスク上のどこに格納されているかを確認すると、次のように表示される場合があります。

/local/path/to/datanode/storage/0/blk_000000000000001  300 MB
/local/path/to/datanode/storage/0/blk_000000000000002  300 MB
/local/path/to/datanode/storage/0/blk_000000000000003  300 MB
/local/path/to/datanode/storage/0/blk_000000000000004  200 MB

ファイルは 300 MB で正確に割り切れないため、ファイルの最終ブロックは、ブロック サイズによるファイルのモジュロとしてサイズ設定されることに注意してください。

ここで、ブロック サイズよりも小さいファイル (たとえば 1 MB) で同じ演習を繰り返し、それがデータ ノードにどのように格納されるかを見てみましょう。

/local/path/to/datanode/storage/0/blk_000000000000005  1 MB

繰り返しになりますが、データ ノードに格納されている実際のファイルは 1 MB であり、299 MB のゼロ パディングを含む 200 MB のファイルではありません(これが混乱の原因だと思います)。

ブロックサイズが効率の要因となる場所は、名前ノードにあります。上記の 2 つの例では、名前ノードはファイル名のマップを維持し、ブロック名とデータ ノードの場所 (および合計ファイル サイズとブロック サイズ) を保持する必要があります。

filename     index     datanode
-------------------------------------------
fileA.txt    blk_01    datanode1
fileA.txt    blk_02    datanode1
fileA.txt    blk_03    datanode1
fileA.txt    blk_04    datanode1
-------------------------------------------
fileB.txt    blk_05    datanode1

fileA.txt に 1 MB のブロック サイズを使用する場合、上記のマップでは 4 ではなく 1100 のエントリが必要になることがわかります (名前ノードでより多くのメモリが必要になります)。また、すべてのブロックをプルバックすると、datanode1 に対して 4 回ではなく 1100 回の RPC 呼び出しを行うことになるため、コストが高くなります。

于 2013-06-22T12:39:55.960 に答える
1

例として、ファイル サイズに関するブロック分割の違いを強調してみます。HDFS には次のものがあります。

Splittable FileA size 1GB
dfs.block.size=67108864(~64MB)

このファイルに対する MapRed ジョブ:

16 splits and in turn 16 mappers.

圧縮された (分割不可能な) ファイルを使用して、このシナリオを見てみましょう。

Non-Splittable FileA.gzip size 1GB
dfs.block.size=67108864(~64MB)

このファイルに対する MapRed ジョブ:

16 Blocks will converge on 1 mapper.

tasktracker が 16 ブロックのデータをフェッチする必要があり、そのほとんどが tasktracker に対してローカルではないため、この状況を事前に回避することをお勧めします。

最後に、ブロック、スプリット、ファイルの関係をまとめると、次のようになります。

                                                             block boundary
|BLOCK           |    BLOCK       |   BLOCK        |   BLOCK ||||||||
|FILE------------|----------------|----------------|---------|
|SPLIT            |                |                |        |

分割はブロック サイズと一致しない可能性があるファイルの分割方法の InputFormat クラス定義に依存するため、分割はブロックを超えて拡張できます。

于 2013-06-22T15:13:52.740 に答える