3

我有大量的日志文件存储在 HDFS 中,如下所示:

2012-10-20 00:05:00; BEGIN
...
SQL ERROR -678: Error message
...
2012-10-20 00:47:20; END

我想知道某个时间范围内某些 sql 错误代码发生的频率,例如:从 2012 年 10 月 20 日凌晨 0:00 到 2012 年 10 月 20 日凌晨 1:00 发生了多少 678 个 SQL 错误。

由于文件通常被分成几个块,它们可以分布在所有数据节点之间。

这样的查询可能吗?我想使用 hadoop mapreduce Java API 或 Apache Pig,但我不知道如何应用时间框架条件。

4

1 回答 1

1

HDFS 在将文件拆分为块时不会考虑新行,因此单行可能会被拆分为两个块。但是,MapReduce 确实如此,因此输入文件中的一行将由单个映射器处理。

2012-10-20 00:05:00;
开始...
SQL 错误 -678:错误消息
...
2012-10-20 00:47:20 ; 结尾

如果文件大于块大小,则上述行更有可能位于两个块中并由不同的映射器处理。可以覆盖FileInputFormat.isSplitable()以确保单个日志文件由单个映射器处理,而不是由多个映射器处理。

Hadoop 将使用 KV 对调用用户定义的映射函数,其中 K 是文件偏移量,值是输入文件中的行。需要一个实例变量来存储 BEGIN 时间,以便在稍后调用用户定义的映射函数时检查 END 时间。

这不是一种有效的方法,因为单个映射器正在处理特定的映射文件并且没有分发。

另一种方法是通过将相关行组合成一行来预处理日志文件。这样,日志文件中的相关行将仅由单个映射器处理。

仅供参考,不使用 FileInputFormat.isSplitable() 的更复杂的方法也是可能的,但这需要解决。

必须评估每种方法的优缺点并选择正确的方法。

于 2012-10-24T12:10:34.213 回答