2

Hadoopの入力および出力形式として機能し、C ++、Java、およびPythonで直接Hadoopとは別に読み取りおよび書き込みが可能な、移植可能なKey-Valueデータファイル形式を探しています。1つの落とし穴...Java以外のマッパーとレデューサー(特にHadoopパイプを介したc ++)での処理をサポートする必要があります。

何か案は?HadoopおよびHadoopパイプと相互運用する独自のポータブルKey-Valueファイル形式を作成する必要がありますか?そのような新しいフォーマットはコミュニティに役立つでしょうか?

長いバージョン: Hadoopシーケンスファイル(およびそれらのいとこであるMap、Set、Array、BloomMap)は、Hadoopを使用する場合の効率的なバイナリキー値データストレージの標準のようです。シーケンスファイルの欠点の1つは、Javaでのみ読み取りと書き込みができることです(シリアル化されたJavaオブジェクトで指定されます)。さまざまなステージへの入力と出力がC++、java、およびpythonから読み取りおよび書き込み可能でなければならない、複雑なマルチステージMapReduceパイプラインを構築したいと思います。さらに、マッピング段階で大規模で高度に最適化されたc ++ライブラリを使用するには、Java以外の言語(つまりc ++)でマッパーとリデューサーを記述できる必要があります。

さまざまな回避策を検討しましたが、どれも魅力的ではないようです。

  1. 変換:各MapReduceステージの前後に変換ステージを追加して、シーケンスファイルと他の言語と互換性のあるポータブル形式の間でステージの入力と出力を変換します。
    • 問題:ステージ間で消費および生成されるデータは非常に大きい(TB)...異なるプログラミング言語で読み取り/書き込みアクセスを取得するためだけに、各ステージでデータを複数回複製するのはコストがかかります。10のステージがありますが、これは私が支払うにはオーバーヘッドが大きすぎます($$$)。
  2. Avroファイル:Avroのポータブルデータファイル形式を使用します。
    • 問題:ポータブルAvroデータファイルをMapReduceの入力または出力形式として機能させるコードはあるようですが、Javaで記述されたマッパーとレデューサーでのみ機能します。avro / mapred / tetherパッケージを介して他の言語でマッパーのサポートを作成することについていくつかの議論を見てきましたが、現在サポートされているのはJavaのみです。ドキュメントから:「現在、テスト目的で実装されているのはJavaフレームワークのみであるため、この機能はまだ有用ではありません。」 http://avro.apache.org/docs/1.5.4/api/java/org/apache/avro/mapred/tether/package-summary.html
  3. Avro File + SWIG:分散キャッシュからアクセスされるカスタムSWIGラップされたc++ライブラリを呼び出すJavaマッパーでAvroデータ形式を使用して実際の処理を実行します。
    • Java文字列の不変性により、コピーが必要なため、SWIGラッパーの作成が面倒で非効率になります。また、この多くのラッピングのレイヤーは、メンテナンス、デバッグ、および構成の悪夢になり始めています。

HadoopおよびHadoopパイプと相互運用するHファイル形式に基づいた独自の言語のポータブルKey-Valueファイル形式を作成することを検討しています...既製のより良い代替手段はありますか?そのようなポータブルフォーマットはコミュニティに役立つでしょうか?

4

1 に答える 1

1

あなたはいくつかの誤った仮定をしたと思います:

シーケンス ファイルの欠点の 1 つは、Java でしか読み書きできないことです (シリアライズされた Java オブジェクトで指定されます)。

シリアル化された Java オブジェクトの意味によって異なります。Hadoop は WritableSerialization クラスを使用して、デフォルトの Java シリアライゼーション メカニズムではなく、シリアライゼーションのメカニズムを提供します。Hadoop を構成して、デフォルトの Java シリアライゼーション ( JavaSerialization)、または選択した任意のカスタム実装(構成プロパティーを使用) を使用できますio.serializations

したがって、Hadoop Writable メカニズムを使用する場合は、シーケンス ファイルを解釈できる C++ 用のリーダーを作成し、シリアライズしたいクラスに相当する c++/python を作成するだけで済みます (ただし、これは維持するのが面倒で、 2 番目の質問へ、アブロ)

さらに、マッピング段階で高度に最適化された大規模な C++ ライブラリを使用するには、Java 以外の言語 (つまり C++) でマッパーとリデューサーを記述できる必要があります。

マッパー/リデューサーを python / c++ / 現在 Hadoop ストリーミングを使用しているものなら何でも記述し、シーケンス ファイルを使用して中間形式を保存できます。ストリーミングに必要なのは、マッパー/リデューサー/コンバイナーが標準入力の入力をkey\tvalueペアで期待し (タブの代わりに区切り文字をカスタマイズできます)、同様の形式で出力することです (これもカスタマイズ可能です)。

より複雑なキー/値のペアをストリーミング マッパー/リデューサーとの間で渡したい場合はどうでしょうか。この場合、contrib/ストリーミング ソース コード、具体的には PipeMapper、PipeReducer、および PipeMapRed クラスのカスタマイズを検討します。たとえば、出力/入力を<Type-int/str,Length-int,Value-byte[]>タプルに修正してから、python / c++ コードを修正して適切に解釈することができます。

これらの変更により、Avro を使用して、Hadoop ストリーミング フレームワーク (Java) と c++/python コードの間のシリアル化に関するコードを管理できます。Avro を使用することもできます。

最後に -クラスAvroAsTextInputFormatAvroTextOutputFormatクラスを調べましたか?それらはまさにあなたが探しているものかもしれません(警告、私はそれらを使用したことがありません)

于 2012-04-19T01:22:35.100 に答える