5

我在S3中有一堆精簡壓縮的服務器日誌,我需要在Elastic MapReduce上使用流處理它們。我如何告訴Amazon和Hadoop這些日誌已經被壓縮(在它們被拉入HFS之前!),以便它們可以在發送到流式映射器腳本之前被解壓縮?將快速壓縮的文件加載到Elastic MapReduce中

我能找到的唯一文檔是http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/HadoopDataCompression.html#emr-using-snappy ,它似乎是指中間壓縮,而不是在到達HFS時被壓縮的文件。

順便說一句,我主要在python工作,所以獎金分,如果你有博託解決方案!

回答

7

答案是,「它不能做到」。至少,不適用於將hadoop流式傳輸到源於hadoop之外的快速壓縮文件的特定情況。 (1)嘗試使用hadoop的內置快速壓縮,如高度無咖啡因所示,或者(2)編寫我自己的流模塊來消耗和解壓縮snappy文件。

對於選項(1),似乎hadoop在使用snappy壓縮文件時向文件添加了一些標記。由於我的文件在hadoop之外使用快速壓縮,hadoop的內置編解碼器無法解壓縮文件。

這個問題的一個症狀是堆空間錯誤:

2013-04-03 20:14:49,739 FATAL org.apache.hadoop.mapred.Child (main): Error running child : java.lang.OutOfMemoryError: Java heap space 
    at org.apache.hadoop.io.compress.BlockDecompressorStream.getCompressedData(BlockDecompressorStream.java:102) 
    at org.apache.hadoop.io.compress.BlockDecompressorStream.decompress(BlockDecompressorStream.java:82) 
    at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:76) 
    at java.io.InputStream.read(InputStream.java:85) 
    ... 

當我切換到一個更大的實例,並拍成了mapred.child.java.opts設置,我得到了一個新的錯誤:

java.io.IOException: IO error in map input file s3n://my-bucket/my-file.snappy 

Hadoop的快速編解碼器不適用於外部生成的文件。

對於選項(2),問題在於hadoop streaming不區分\ n,\ r和\ r \ n換行符。由於快速壓縮最終會在整個壓縮文件中散佈這些字節代碼,這是致命的。這是我的錯誤跟蹤:

2013-04-03 22:29:50,194 WARN org.apache.hadoop.mapred.Child (main): Error running child 
java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 1 
    at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:372) 
    at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:586) 
    at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:135) 
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57) 
    ... 

隨着Hadoop的Java類的一些工作(見here,例如)我們或許可以修復\ r VS \ n問題。但正如我最初所說,我的目標是在hadoop流模塊內部構建,而不需要接觸Java。有了這個限制,似乎沒有辦法解決這個問題。

最後,我回到了生成這個羣集消耗的文件的傢伙,並說服他們切換到gzip或lzo。在選項(2)中,我玩弄了不同字符上的分割記錄(例如textinputformat.record.delimiter = X),但它感覺非常黑,並且無論如何都不起作用。

PPS - 另一個解決方法是編寫腳本從S3下載文件,解壓縮它們,然後運行-copyFromLocal將它們拖入HDFS。從計算上來說,這沒有什麼問題,但從工作流的角度來看,它會引入各種麻煩。

1

假設您使用的是TextInputFormat(或其子類之一),帶有.snappy擴展名的壓縮輸入文件會自動處理。

你可能要考慮使用lzo壓縮(.gz擴展)而不是snappy。你放棄了一些壓縮速度,以獲得更好的壓縮比和一個可拆分的輸入文件。 Cloudera提到這in their blog

One thing to note is that Snappy is intended to be used with a container format, like Sequence Files or Avro Data Files, rather than being used directly on plain text, for example, since the latter is not splittable and can’t be processed in parallel using MapReduce. This is different to LZO, where is is possible to index LZO compressed files to determine split points so that LZO files can be processed efficiently in subsequent processing.

+0

我聽說你對LZO和snappy的看法,對於其他人在未來做類似的事情,我也推薦LZO。就我而言,管理存儲到S3的團隊有其他原因希望更加快樂,並且不會對我們在hadoop上的表現造成太大的傷害。所以我們堅持快速壓縮。 – Abe 2013-04-03 20:08:49

+0

此外,您提到的基於魔術文件擴展名的檢測不適用於許多hadoop版本。我正在使用AWS EMR AMI 2.3.3,版本1.0.3,並沒有在那裏工作。我也嘗試了幾個其他的EMR版本,但沒有喜悅。 – Abe 2013-04-03 20:11:19

相關問題