Daily Archives: 01/23/2014

Hadoopフレンドリーなデータとは

Pocket

 

ログは1行1イベントに

何を言っとるんだお前はという感じであるが、つまりこういう事である。

通常、ログは1行が1イベントである。
たとえばapacheのログやらなにやら、みんなそうである。
少なくともUNIX系のシステムであれば、これは常識である。
しかし、この世の中、UNIX系の常識が通用しないログだって山ほどあるのである。

1イベントが複数行にわたるログがなぜいけないか。

たとえば以下の様な擬似ログを考えてみよう。

まったく関係のない話だが、以下のデータは手元にあるLIFEのノートから適当にでっち上げた。
冒頭にタイムスタンプがあり、イベントの内容が記される、典型的なログである。

しかしこれが、以下のように複数行にわたって記録(あるいは表示)される、こういうログを相手にすることだってあるのだ。

 

これは主に可読性を意識したせいであろうが、こういったログをHadoopで扱うのは難しい。

Hadoopのデータの扱い方

というのも、Hadoopは分散処理のためにログを分割するからだ(デフォルトでは64MBごと)。

しかもその分割は、単純にサイズのみで判断され、文脈は考慮されない。
上のログで言えば、Nobleの手前で切られてしまってログとして意味がなくなってしまうことだってある。

これを避けるには、Hadoopにファイルそのものではなくて、ファイルリストを与える手があるけれども、それではHadoopの長所を活かせない。
ファイルリストは綺麗に分割されるけど、ファイルの大きさはまちまちだから。

ログの整形

というわけで、こういったログを扱う前に、下準備として1行1イベントにまとめてしまおう。

まとめ自体もHadoopで処理してしまえば楽である。
Hadoopの象本Appendix Cに良い例があるのでこれを使う。
ここでfiles.txtは処理するログファイルをリストしたものとする。
また、concat.shは1行1イベントにまとめるスクリプトとする。

 

reduceは必要ないのでmapred.reduce.tasks=0。
重複して書き込んでほしくないのでmapred.map.tasks.speculative.execution=false。
タイムアウトは長めに。
mapが一回に処理するファイルはひとつにしたいので、-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat 。

以上