5

Java 以外の言語でバイナリ データを分析できる「typedbytes」または「rawbytes」モードの Hadoop ストリーミングによって解決される問題があります。(これがないと、ストリーミングは一部の文字 (通常は \t と \n) を区切り文字として解釈し、utf-8 以外の文字について文句を言います。すべてのバイナリ データを Base64 に変換すると、ワークフローが遅くなり、目的が達成できなくなります。)

これらのバイナリ モードは、HADOOP-1722によって追加されました。Hadoop ストリーミング ジョブを呼び出すコマンド ラインで、「-io rawbytes」を使用すると、データを 32 ビット整数サイズとして定義し、その後にそのサイズの生データを続けます。「-io typedbytes」を使用すると、データを 1 として定義できます。 -ビット ゼロ (生バイトを意味する)、32 ビット整数サイズ、そのサイズの生データが続きます。これらの形式 (1 つまたは複数のレコード) でファイルを作成し、 typedbytes.pyの出力と照合して正しい形式であることを確認しました。また、考えられるすべてのバリエーション (ビッグ エンディアン、リトルエンディアン、さまざまなバイト オフセットなど) も試しました。CDH4 のHadoop 0.20 を使用していますtypedbytes 処理を実装するクラスがあり、「-io」スイッチが設定されているときにそれらのクラスに入ります。

「hadoop fs -copyFromLocal」でバイナリ ファイルを HDFS にコピーしました。map-reduce ジョブへの入力として使用しようとすると、指定した長さ (たとえば 3 バイト) のバイト配列を作成しようとする行で OutOfMemoryError で失敗します。番号を間違って読み取っていて、代わりに巨大なブロックを割り当てようとしているに違いありません。それにもかかわらず、それはマッパーにレコードを取得することに成功し (前のレコード? わからない)、それを標準エラーに書き込むので、それを見ることができます。レコードの先頭には常にバイトが多すぎます。たとえば、ファイルが「\x00\x00\x00\x00\x03hey」の場合、マッパーは「\x04\x00\x00\x00\x00\x00」と表示します。 \x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x00\x03hey" (再現可能なビットですが、パターンはわかりません)。

このトークの 5 ページから、ストリーミングの「loadtb」および「dumptb」サブコマンドがあることを知りました。これらは、HDFS との間でコピーし、SequenceFile 内の入力されたバイトを 1 つのステップでラップ/ラップ解除します。「-inputformat org.apache.hadoop.mapred.SequenceFileAsBinaryInputFormat」を使用すると、Hadoop は SequenceFile を正しくアンパックしますが、まったく同じ方法で、含まれている typedbytes を誤って解釈します。

さらに、この機能のドキュメントは見つかりません。2 月 7 日 (私は自分自身に電子メールで送信しました)、Apache の streaming.html ページで簡単に言及されましたが、この r0.21.0 Web ページは削除されており、r1.1.1 の同等のページには rawbytesについての言及がありません。またはタイプバイト。

私の質問は、Hadoop ストリーミングで rawbytes または typedbytes を使用する正しい方法は何ですか? 誰かがそれを機能させたことがありますか?もしそうなら、誰かがレシピを投稿できますか?これは、Hadoop Streaming でバイナリ データを使用したい人にとっては問題になるように思われます。

PS DumboHadoopy、およびrmrはすべてこの機能を使用していることに気付きましたが、Python ベースまたは R ベースのフレームワークを介さずに直接使用する方法があるはずです。

4

3 に答える 3

5

わかりました、うまくいく組み合わせを見つけましたが、それは奇妙です.

  1. ドキュメントに従って、または typedbytes.py を模倣し、ローカル ファイルシステムに有効な typedbytes ファイルを準備します。

  2. 使用する

    hadoop jar path/to/streaming.jar loadtb path/on/HDFS.sequencefile < local/typedbytes.tb
    

    typedbytes を SequenceFile にラップし、それを HDFS に 1 ステップで配置します。

  3. 使用する

    hadoop jar path/to/streaming.jar -inputformat org.apache.hadoop.mapred.SequenceFileAsBinaryInputFormat ...
    

    マッパーが SequenceFile から入力を取得する map-reduce ジョブを実行します。-io typedbytesor-D stream.map.input=typedbytesは使用しないでください--- typedbytes を明示的に要求すると、質問で説明した誤解につながります。しかし心配はいりません。Hadoop ストリーミングは、'\n' 文字ではなく、バイナリ レコード境界で入力を分割します。データは、次のように「\t」と「\n」で区切られた「生データ」としてマッパーに到着します。

    1. 長さを表す 32 ビットの符号付き整数 (注: 型文字なし)
    2. その長さの生のバイナリのブロック: これがキーです
    3. '\t' (タブ文字...なぜ?)
    4. 長さを表す 32 ビットの符号付き整数
    5. その長さの生のバイナリのブロック: これが値です
    6. '\n' (改行文字... ?)
  4. マッパーからレデューサーに生データを追加で送信する場合は、追加します

    -D stream.map.output=typedbytes -D stream.reduce.input=typedbytes
    

    Hadoop コマンド ラインに追加し、マッパーの出力とリデューサーの予想される入力を有効な typedbytes としてフォーマットします。キーと値のペアも交互に使用されますが、今回はタイプ文字があり、'\t' と '\n' はありません。Hadoop ストリーミングは、これらのペアをバイナリ レコード境界で正しく分割し、キーでグループ化します。

私が見つけたstream.map.outputとに関する唯一のドキュメントは、2009 年 2 月 6 日に開始されたHADOOP-1722交換にありました。stream.reduce.input

このレシピでは、入力に対して厳密な型指定は提供されません。型文字は、SequenceFile を作成し、-inputformat. ただし、'\n' ではなく、バイナリ レコード境界での分割が提供されます。これは非常に重要なことであり、マッパーとリデューサーの間の強力な型指定です。

于 2013-03-02T08:37:55.613 に答える
0

どうやら、ストリーミング用の JustBytes IO モードのパッチがあり、入力ファイル全体をマッパー コマンドにフィードします。

https://issues.apache.org/jira/browse/MAPREDUCE-5018

于 2014-10-27T09:08:41.113 に答える