首先翻译一下官方文档,然后写一个小的案例进行理解。更详细的内容可以参考最新的文档和源码(https://github.com/Yelp/mrjob)
输入输出协议
官方链接:https://pythonhosted.org/mrjob/guides/writing-mrjobs.html#protocols
mrjob假设所有数据都是换行符分隔的字节。它使用protocols
序列和反序列化这些字节。每个job
(作业)都一个输入protocol
,一个输出procotol
和一个内部procotol
。
一个procotol
具有read()
方法和write()
方法。该 read()
方法将字节转换为python对象的键值(key和value)对。该write()
方法将一对Python对象
(表示key和value组成的键值对)转换回字节。
输入procotol
用于读取字节并发送给第一个mapper
(或者reducer,如果第一步骤中不使用mapper)。输出procotol
将最后一步输出以字节形式输出到输出文件。内部procotol
转换一个步骤的输出到下一个步骤的输入,如果该作业具有一个以上的步骤。
您可以指定作业使用的procotol
,如下所示:
class MyMRJob(mrjob.job.MRJob):
# these are the defaults
INPUT_PROTOCOL = mrjob.protocol.RawValueProtocol
INTERNAL_PROTOCOL = mrjob.protocol.JSONProtocol
OUTPUT_PROTOCOL = mrjob.protocol.JSONProtocol
默认输入协议是RawValueProtocol
,它只把每一行读成一个str。(该行不会有尾随换行符,因为MRJob
会将它删除 )。因此,默认情况下,在作业的第一步可以看到将每行输入转化为(None, line)的键值对。
默认输出和内部协议都是JSONProtocol
,它读取和写入由制表符分隔的JSON字符串。(默认情况下,Hadoop Streaming在对数据进行排序时使用制表符分隔一行内的键值对。)
如果你的头有点疼,可以这样想:RawValueProtocol
当你想读或写原始文本行时使用。JSONProtocol
当你想要读取或写入键值对(JSON编码字节的键值对)时使用。
注意: Hadoop Streaming不使用JSON或mrjob协议。它只是通过对第一个制表符前面的内容进行字符串比较来对行进行分组。
可以通过查看mrjob.protocol(https://pythonhosted.org/mrjob/protocols.html#module-mrjob.protocol) 来了解mrjob内置协议的完整列表。
脚注:
- [1] 经验丰富的Pythonistas可能会注意到,str在Python 2上是一个字节串,但在Python 3上是Unicode。这是对的!
RawValueProtocol
是两个不同协议之一的别名,具体取决于您的Python版本。 - [2]
JSONProtocol
是四种不同实现之一的别名; 我们尝试使用(更快)ujson库(如果可用),如果没有,尝试rapidjson或者simplejson库。在前边都没有的情况下, 使用python内置json模块。
数据流实例
让我们从多步骤工作中重新审视我们的示例。它有两个步骤,并将纯文本文件作为输入
class MRMostUsedWord(MRJob):
def steps(self):
return [
MRStep(mapper=self.mapper_get_words,
combiner=self.combiner_count_words,
reducer=self