Flumeを使用してHDFSにログを収集しています。テストケースでは、ログ収集プロセスが実際の使用に合わせてスケーリングされているため、小さなファイル(〜300kB)があります。
これらの小さなファイルをHDFSブロックサイズ(64MB)に近い大きなファイルに結合する簡単な方法はありますか?
GNUcoreutilsスプリットがその仕事をすることができます。
ソースデータが行であり(私の場合はそうです)、1行が前後84 bytes
にある場合、HDFSブロックには次の行64MB
が含まれる可能性があります。800000
hadoop dfs -cat /sourcedir/* | split --lines=800000 - joined_
hadoop dfs -copyFromLocal ./joined_* /destdir/
または--line-bytes
オプション付き:
hadoop dfs -cat /sourcedir/* | split --line-bytes=67108864 - joined_
hadoop dfs -copyFromLocal ./joined_* /destdir/
私の現在の解決策は、レデューサーの数を制限しながら、効果的に何もしないMapReduceジョブを作成することです。各レデューサーはファイルを出力するので、これはそれらを一緒にキャットします。各行に元のファイルの名前を追加して、ファイルの出所を示すことができます。
私が気付いていない、これを行うための標準的または証明された最良の方法があるかどうかを聞くことにまだ興味があります。
media6degreesによってオープンソース化されたFileCrusherを見てください。少し古くなっているかもしれませんが、ソースをダウンロードして変更を加えたり、貢献したりすることができます。JARとソースは次の場所にあります:http://www.jointhegrid.com/hadoop_filecrush/index.jsp
これは基本的に、小さなファイルをマージするためのmap-reduce手法です。