7

Hadoopは初めてです。最近、hdfs / hadoop上の多くの小さなファイルを処理(読み取りのみ)しようとしています。平均ファイルサイズは約1kbで、ファイル数は10M以上です。いくつかの制限があるため、プログラムはC++で作成する必要があります。

これは単なるパフォーマンス評価であるため、データノードには5台のマシンのみを使用します。各データノードには5つのデータディスクがあります。

パフォーマンスベースラインを構築するために(HDFSからではなく)ハードディスクから直接ファイルを読み取る小さなC++プロジェクトを作成しました。プログラムは、ディスクごとに4つの読み取りスレッドを作成します。パフォーマンスの結果は、ディスクあたり約14MB/秒になります。合計スループットは約14MB/秒*5* 5 = 350MB /秒(14MB/秒*5ディスク*5マシン)です。

ただし、このプログラム(C ++を引き続き使用し、libhdfs.soに動的にリンクされ、4 * 5 * 5 = 100スレッドを作成)がhdfsクラスターからファイルを読み取る場合、スループットは約55MB/秒になります。

このプログラミングがmapreduceでトリガーされた場合(hadoopストリーミング、5つのジョブ、それぞれに20のスレッドがあり、スレッドの総数は100のままです)、スループットは約45MB/秒に低下します。(私はそれがいくつかの簿記プロセスによって遅くなると思います)。

HDFSが実現できる妥当なパフォーマンスとは何か疑問に思っています。ご覧のとおり、ネイティブコードと比較すると、データスループットは約1/7です。それは私の設定の問題ですか?またはHDFSの制限?またはJavaの制限?私のシナリオに最適な方法は何ですか?シーケンスファイルは(大いに)役立ちますか?期待できるネイティブIO読み取りと比較した場合の妥当なスループットはどれくらいですか?

これが私の設定の一部です:

NameNodeヒープサイズ32G。

ジョブ/タスクノードのヒープサイズは8Gです。

NameNodeハンドラー数:128

DataNodeハンドラー数:8

DataNode転送スレッドの最大数:4096

1GBpsイーサネット。

ありがとう。

4

3 に答える 3

8

HDFSは、実際には多くの小さなファイル用に設計されていません。

読み取る新しいファイルごとに、クライアントはnamenodeと通信する必要があります。これにより、ファイルのブロックの場所が指定され、クライアントはデータノードからデータをストリーミングします。

さて、最良の場合、クライアントはこれを一度実行すると、それがデータを保持しているマシンであることがわかり、ディスクから直接読み取ることができます。これは高速になります:直接ディスク読み取りに匹敵します。

データを保持しているのがマシンでない場合は、ネットワークを介してデータをストリーミングする必要があります。次に、ネットワークI / Oの速度に制限されます。これはひどいことではありませんが、ディスクの直接読み取りよりも少し遅いです。

ただし、さらに悪いケースが発生しています。namenodeとの通信のオーバーヘッドが大きくなる場合です。1KBのファイルだけで、実際のデータと同じ量のメタデータを交換できるようになります。クライアントは、各ファイルからデータを取得するために、2つの別々のネットワーク交換を行う必要があります。これに加えて、namenodeはおそらくこれらのさまざまなスレッドすべてによって打撃を受けているため、ボトルネックになる可能性があります。

ですから、あなたの質問に答えるために、はい、HDFSを使用するように設計されていないものに使用すると、遅くなります。小さなファイルをマージし、MapReduceを使用してデータの局所性を取得すると、パフォーマンスが大幅に向上します。実際、シーケンシャルディスク読み取りをより有効に活用できるため、1つの大きなHDFSファイルからの読み取りが、多くの小さなローカルファイルの読み取りよりもさらに高速であったとしても驚かないでしょう。

于 2012-12-21T18:29:48.790 に答える
3

Joeが言ったことに加えて、HDFSと他のファイルシステムのもう1つの違いは、FSブロックサイズがKBの順に。そのため、HDFSは、小さなファイルを大量に処理するのではなく、いくつかの大きなファイルを処理するのに適していると常に言われています。この背後にある理由は、最近cpu、ramなどのコンポーネントが大幅に進歩しているにもかかわらず、ディスクI/Oはまだそれほど進歩していない領域であるという事実です。これは、(従来のFSとは異なり)非常に大きなブロックを持ち、ディスクの使用をできるだけ少なくすることの背後にある意図でした。

さらに、ブロックサイズが小さすぎると、ブロック数が多くなります。これは、より多くのメタデータを意味します。より多くの情報をメモリにロードする必要があるため、これもパフォーマンスを低下させる可能性があります。HDFSのオブジェクトと見なされるブロックごとに、約200Bのメタデータが関連付けられています。小さなブロックがたくさんある場合は、メタデータが増えるだけで、RAMの問題が発生する可能性があります。

同じ問題について話しているClouderaのブログセクションに非常に良い投稿があります。ここにアクセスできます。

于 2012-12-21T19:21:04.720 に答える
1

制限を理解して、いつ制限に達するかを見てみましょう
。a)ファイルが置かれている場所の情報を提供するためにnamenodeが必要です。この数は1秒あたり約数千と推測できます。詳細については、 https: //issues.apache.org/jira/browse/HADOOP-2149を参照してください。この数を10000Kとすると、1Kファイルの場合は約10MB秒の情報を取得できるはずです。(どういうわけかあなたはもっと得る...)。
b)HDFSのオーバーヘッド。このオーバーヘッドは主に、スループットではなくレイテンシーにあります。HDFSは、並列で多数のファイルを提供するように調整できます。HBaseがそれを実行しており、HBaseチューニングガイドから設定を取得できます。ここでの問題は、実際に必要なデータノードの量です
。c)LAN。ネットワークからデータを移動するため、1GBのイーサネットスループット制限に達する可能性があります。(私はそれがあなたが得たものだと思います。

また、Joeに同意する必要があります。HDFSはシナリオ用に構築されていないため、他のテクノロジー(Hadoopスタックが好きな場合はHBaseなど)を使用するか、ファイルを一緒に圧縮して、たとえばシーケンスファイルにする必要があります。

HDFSからより大きなファイルを読み取ることに関して-DFSIOベンチマークを実行すると、それがあなたの番号になります。
同時に、単一ホスト上のSSDも完全にソリューションになる可能性があります。

于 2012-12-23T11:19:21.730 に答える