使用mrjob处理LZO序列文件

时间:2013-09-18 20:55:36

标签: python hadoop lzo mrjob

我正在使用mrjob编写一个任务,使用Google Ngrams数据计算各种统计信息:https://aws.amazon.com/datasets/8172056142375670

我开发了&使用制表符分隔文本中的未压缩数据子集在本地测试我的脚本。一旦我尝试运行这个工作,我就收到了这个错误:

Traceback (most recent call last):
  File "ngram_counts.py", line 74, in <module>
    MRNGramCounts.run()
  File "/usr/lib/python2.6/dist-packages/mrjob/job.py", line 500, in run
    mr_job.execute()
  File "/usr/lib/python2.6/dist-packages/mrjob/job.py", line 509, in execute
    self.run_mapper(self.options.step_num)
  File "/usr/lib/python2.6/dist-packages/mrjob/job.py", line 574, in run_mapper
    for out_key, out_value in mapper(key, value) or ():
  File "ngram_counts.py", line 51, in mapper
    (ngram, year, _mc, _pc, _vc) = line.split('\t')
ValueError: need more than 2 values to unpack
(while reading from s3://datasets.elasticmapreduce/ngrams/books/20090715/eng-1M/5gram/data)

大概这是因为公共数据集的压缩方案(来自上面的URL链接):

  

我们将数据集存储在Amazon S3中的单个对象中。该文件在   块级LZO压缩的序列文件格式。序列   file key是存储为LongWritable和的数据集的行号   值是存储为TextWritable的原始数据。

有关如何设置可以处理这些文件的工作流程的任何指导?我已经详尽地搜索了一些提示,但没有找到任何有用的东西......

(我是mrjob和Hadoop的亲戚。)

1 个答案:

答案 0 :(得分:2)

我终于弄明白了。看起来EMR会为您处理LZO压缩,但对于序列文件格式,您需要将以下HADOOP_INPUT_FORMAT字段添加到MRJob类:

class MyMRJob(MRJob):

    HADOOP_INPUT_FORMAT = 'org.apache.hadoop.mapred.SequenceFileAsTextInputFormat'

    def mapper(self, _, line):
        # mapper code...

    def reducer(self, key, value):
        # reducer code...

还有另一个问题(引自AWS主持的Google NGrams页面):

  

序列文件键是存储为LongWritable的数据集的行号,值是存储为TextWritable的原始数据。

这意味着每行都有前缀和额外的Long + TAB,因此您在mapper方法中执行的任何行解析都需要考虑前置信息。