根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录
Posted
技术标签:
【中文标题】根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录【英文标题】:Write some data (lines) from my mappers to separate directories depending on some logic in my mapper code 【发布时间】:2012-06-18 21:59:35 【问题描述】:我正在使用 mrjob 来满足我的 EMR 需求。
如何根据我的映射器代码中的一些逻辑将一些数据(行)从我的映射器写入“单独的目录”:
tar gzip 和
在作业完成/突然终止后上传到单独的 S3 存储桶(取决于目录名称)?
我猜“--output-dir
”选项只允许您将最终作业输出上传到该目录,但我想不时从我的映射器写入其他目录。
【问题讨论】:
【参考方案1】:我认为 Hadoop 的 MultipleOutput
功能可以帮助您,在您的自定义 outputFormat
中您可以指定路径和文件名。
【讨论】:
我认为您目前可能不会在 Hadoop Streaming 中执行此操作,hadoop.apache.org/common/docs/r0.20.2/…,它说您必须使用自定义 jar。但我可能错了 您当然可以将自定义 jar 作为 Hadoop 流式作业运行。示例命令应如下所示: ruby elastic-mapreduce –jobflow不,你不能在传统意义上。
原因:在运行 Hadoop 集群时,MrJob 内部使用 Hadoop 流来运行 map/reduce 作业我假设 Amazon Elastic M/R 与 Hadoop 集群相同。
--output-dir
实际上是 Hadoop 流的输入,它指定了 reducer 输出的收集位置。您不能使用这种机制将数据隔离到不同的文件夹中。
[编辑:回应评论]
我的理解是boto只是一个连接亚马逊服务和访问ec2和s3等的库。
我猜,在非传统意义上,您仍然可以写入不同的目录。
我没有测试过这个想法,也不推荐这种方法。这就像打开一个文件并直接在减速器中写入它。理论上你可以这样做。而不是仅仅将 reducer 输出写入 std.out。您可以直接打开并写入 S3 对象。您必须确保在生成多个减速器时打开不同的文件。
这是我在将 MrJob 与 Hadoop 集群一起使用时学到的:http://pyfunc.blogspot.com/2012/05/hadoop-map-reduce-with-mrjob.html
【讨论】:
深入思考:MrJob 附带了某个版本的 boto。现在我可以使用它来写入本地文件夹,或者失败,写入“远程”S3 存储桶吗? 我仍在寻找一种将 PUT 数量减少到 S3 的方法(现在我正在为我得到的每一行触发至少一个 PUT) 另外,写入 STDERR 的数据最终会流向 MrJob? (我假设所有 STDOUT 输出都到 '--output-dir' 指向的位置) @newToFlume:两个日志文件。见hadoop.apache.org/common/docs/r0.17.0/… 该链接似乎对 Hadoop Streaming 没有用处,但感谢 Ashish 的跟进。【参考方案3】:您可以按照创建自定义 Jar 的方法并自定义您的 OutputFormat
,以便在不同的文件夹/文件中多路复用输出。您应该创建一个MultipleTextOutputFormat
的子类并覆盖其中的一些方法(主要是generateFileNameForKeyValue(Text key, Text value, String leaf)
和generateActualKey(Text key, Text value)
)。
更多详情可以参考:http://www.infoq.com/articles/HadoopOutputFormat
【讨论】:
以上是关于根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录的主要内容,如果未能解决你的问题,请参考以下文章