根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录

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 --jar --arg --arg --step-name "我的流媒体作业步骤"【参考方案2】:

不,你不能在传统意义上。

原因:在运行 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

【讨论】:

以上是关于根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录的主要内容,如果未能解决你的问题,请参考以下文章

了解 HIVE 数据库中的映射器和缩减器

简单的自动映射器示例

Spark - 如何使用有状态映射器对已排序的 RDD 进行平面映射?

从文件中为hadoop中的映射器创建自定义键值

将数据上传/插入到 HDFS 时是不是涉及映射器减速器?

Spring映射器适配器解析器