1

我目前在 10 个服务器的 hadoop 集群上处理大约 300 GB 的日志文件。我的数据保存在名为 YYMMDD 的文件夹中,因此可以快速访问每一天。

我的问题是我今天刚刚发现我的日志文件中的时间戳是 DST(GMT -0400)而不是预期的 UTC。简而言之,这意味着 logs/20110926/*.log.lzo 包含从 2011-09-26 04:00 到 2011-09-27 20:00 的元素,它几乎破坏了对该数据所做的任何 map/reduce(即生成统计数据)。

有没有办法做一个映射/减少工作来正确地重新分割每个日志文件?据我所知,似乎没有办法使用流式传输输出文件 A 中的某些记录和输出文件 B 中的其余记录。

这是我目前使用的命令:

/opt/hadoop/bin/hadoop jar /opt/hadoop/contrib/streaming/hadoop-streaming-0.20.2-cdh3u1.jar \
-D mapred.reduce.tasks=15 -D mapred.output.compress=true \
-D mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec \
-mapper map-ppi.php -reducer reduce-ppi.php \
-inputformat com.hadoop.mapred.DeprecatedLzoTextInputFormat \
-file map-ppi.php -file reduce-ppi.php \
-input "logs/20110922/*.lzo" -output "logs-processed/20110922/"

我对 java 和/或创建自定义类一无所知。我确实尝试过发布在http://blog.aggregateknowledge.com/2011/08/30/custom-inputoutput-formats-in-hadoop-streaming/的代码(几乎复制/粘贴了那里的内容)但我不能根本无法让它工作。无论我尝试什么,我都会收到“-outputformat:找不到类”错误。

非常感谢您的时间和帮助:)。

4

2 回答 2

1

据我所知,似乎没有办法使用流式传输输出文件 A 中的某些记录和输出文件 B 中的其余记录。

通过使用自定义Partitioner,您可以指定哪个键进入哪个减速器。默认情况下使用HashPartitioner。看起来唯一的其他 Partitioner Streaming 支持是KeyFieldBasedPartitioner

您可以在此处的 Streaming 上下文中找到有关 KeyFieldBasedPartitioner 的更多详细信息。您无需了解 Java 即可使用 Streaming 配置 KeyFieldBasedPartitioner。

有没有办法做一个映射/减少工作来正确地重新分割每个日志文件?

您应该能够编写 MR 作业来重新拆分文件,但我认为 Partitioner 应该可以解决问题。

于 2011-09-27T07:25:48.177 回答
0

自定义 MultipleOutputFormat 和 Partitioner 似乎是按天拆分数据的正确方法。

作为那篇文章的作者,很抱歉让您度过了如此艰难的时光。听起来如果您收到“找不到类”错误,那么在您将其包含在“-libjars”中后,您的自定义输出格式没有找到一些问题。

于 2012-01-29T19:21:42.033 回答