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 Dumbo、Hadoopy、およびrmrはすべてこの機能を使用していることに気付きましたが、Python ベースまたは R ベースのフレームワークを介さずに直接使用する方法があるはずです。