我正在玩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
我当前的线性程序读取文件,记住内存中的启动事件,并在找到相应的结束事件后将经过的时间写入文件(当前忽略了包含其他事件的行,ERROR事件使UUID无效它也将被忽略) 1
我想将其移植到Hadoop / MapReduce程序中。但我不知道如何匹配条目。拆分/标记文件很容易,我想找到匹配将是Reduce-Class。但那会是什么样子? 如何在MapReduce作业中找到mathing条目?
请记住,我的主要目标是了解Hadopo / MapReduce;欢迎链接到Pig和其他Apache程序,但我想用纯Hadoop / MapReduce来解决这个问题。谢谢。
1) 由于日志是从正在运行的应用程序中获取的,因此一些启动事件可能还没有相应的结束事件,并且由于日志文件拆分,将会有没有启动事件的结束事件< / em>的
答案 0 :(得分:8)
如果您在地图中将UUID作为键发出:emit(<uuid>, <event, timestamp>)
,您将在reduce中收到此UUID的所有事件:
key = UUID, values = {<event1, timestamp1>, <event2, timestamp2>}
然后,您可以按时间戳对事件进行排序,并决定是否将它们发送到结果文件中。
额外奖励:您可以使用job.setSortComparatorClass();
来设置自己的排序类,这样您就可以在减少的时间戳中对您的条目进行排序:
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);
...
答案 1 :(得分:3)
我认为你可以通过让你的map函数输出UUID作为其键,并将该行的其余部分作为其值来输出。然后,reduce函数将传递具有相同UUID的所有日志条目的集合。当它处理它们时,它可以跟踪它看到的各种事件并相应地采取行动 - 例如,当它看到START事件时,它可以将局部变量设置为从起始线提取的时间,然后当它看到STOP时事件,它可以从中提取时间,减去开始时间,并输出差异(如果它在START之前看到STOP,也会这样做。)