4

我正在玩 Hadoop 并在 Ubuntu 上建立了一个两节点集群。WordCount 示例运行良好。

现在我想自己写一个MapReduce程序来分析一些日志数据(主要原因:看起来很简单,我有很多数据)

日志中的每一行都有这种格式

<UUID> <Event> <Timestamp>

其中事件可以是 INIT、START、STOP、ERROR 和其他一些。我最感兴趣的是同一 UUID 的 START 和 STOP 事件之间经过的时间。

例如,我的日志包含这样的条目

35FAA840-1299-11DF-8A39-0800200C9A66 START 1265403584
[...many other lines...]
35FAA840-1299-11DF-8A39-0800200C9A66 STOP 1265403777

我当前的线性程序读取文件,记住内存中的开始事件,并在找到相应的结束事件后将经过的时间写入文件(当前忽略具有其他事件的行,错误事件使 UUID 无效,它将也可以忽略)1

我想将此移植到 Hadoop/MapReduce 程序。但我不确定如何匹配条目。拆分/标记文件很容易,我想找到匹配项将是一个 Reduce-Class。但那会是什么样子呢?如何在 MapReduce 作业中找到数学条目?

请记住,我的主要重点是了解 Hadopo/MapReduce;欢迎链接到 Pig 和其他 Apache 程序,但我想用纯 Hadoop/MapReduce 解决这个问题。谢谢你。

1) 由于日志是从一个正在运行的应用程序中获取的,由于日志文件拆分,一些开始事件可能还没有对应的结束事件,并且会有没有开始事件的结束事件

4

2 回答 2

8

如果您在 map 中发出 UUID 作为键:emit(<uuid>, <event, timestamp>)您将在 reduce 中收到此 UUID 的所有事件: key = UUID, values = {<event1, timestamp1>, <event2, timestamp2>}

然后您可以按时间戳对事件进行排序,并决定是否将它们发送到结果文件中。

奖励:您可以job.setSortComparatorClass();用于设置自己的排序类,因此您将在 reduce 中根据时间戳对条目进行排序:

public static class BNLSortComparator extends Text.Comparator {
  public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
    String sb1, sb2;
    try {
      sb1 = Text.decode(b1, s1, l1);
      ...
于 2010-02-05T21:36:22.677 回答
3

我认为你可以通过让你的地图函数输出 UUID 作为它的键和行的其余部分作为它的值来做到这一点。然后,reduce 函数将传递具有相同 UUID 的所有日志条目的集合。当它处理它们时,它可以跟踪它看到的各种事件并采取相应的行动 - 例如,当它看到一个 START 事件时,它可以将一个局部变量设置为从起始行提取的时间,然后当它看到一个 STOP事件它可以从中提取时间,减去开始时间,并输出差值(如果它在开始之前看到停止,则执行类似操作)。

于 2010-02-05T21:36:08.870 回答