2013-12-08 68 views
3

下面是一个日志文件:使用MapReduce的分析日志文件

2011-10-26 06:11:35 user1 210.77.23.12 
2011-10-26 06:11:45 user2 210.77.23.17 
2011-10-26 06:11:46 user3 210.77.23.12 
2011-10-26 06:11:47 user2 210.77.23.89 
2011-10-26 06:11:48 user2 210.77.23.12 
2011-10-26 06:11:52 user3 210.77.23.12 
2011-10-26 06:11:53 user2 210.77.23.12 
... 

我想按降序排列各行使用的MapReduce由第三归档(用户)的日志记录次数进行排序。在另一个词,我想显示的结果为:

user2 4 
user3 2 
user1 1 

现在我有两个问题:

  1. 默认情况下,MapReduce的将分裂与空间日志文件回车,但我只需要每行提出第三条,也就是我不在乎字段如2011-10-26,06:11:35,210.77.23.12,怎么样让MapReduce忽略它们并拿起用户提交?

  2. 默认情况下,MapReduce的将结果通过关键代替排序。如何让MapReduce对结果排序(记录时间)?

谢谢。

回答

2

关于第一个问题:

你或许应该整条生产线传递给映射器和只保留第三令牌映射和地图(user,1)每次。

public class AnalyzeLogs 
{  
    public static class FindFriendMapper extends Mapper<Object, Text, Text, IntWritable> { 

    public void map(Object, Text value, Context context) throws IOException, InterruptedException 
    {  
     String tempStrings[] = value.toString().split(","); 
     context.write(new Text(tempStrings[2]), new IntWritable(1)); 
    } 
} 

对于第二个问题,我相信你不能避免在第二个MR Job之后(我想不出任何其他方式)。所以第一份工作的缩减器只会聚合这些值并给出每个键的总和,按键排序。这还不是你需要的。

因此,您将此作业的输出作为输入传递给第二个MR作业。这项工作的目标是在传递给reducer之前按价值做一些特殊的分类(这绝对不会)。

我们的映射器的第二件事会有如下:

public static class SortLogsMapper extends Mapper<Object, Text, Text, NullWritable> { 

public void map(Object, Text value, Context context) throws IOException, InterruptedException 
{  
    context.write(value, new NullWritable()); 
} 

正如你所看到的,我们不为这个映射器使用价值可言。相反,我们创建了一个密钥,包含我们的值(我们的密钥是key1 value1格式)。 现在还有什么要做,是要指定框架,它应该基于value1而不是整个key1 value1进行排序。因此,我们将实现一个自定义的SortComparator

public static class LogDescComparator extends WritableComparator 
{ 
    protected LogDescComparator() 
    { 
     super(Text.class, true); 
    } 

    @Override 
    public int compare(WritableComparable w1, WritableComparable w2) 
    { 

     Text t1 = (Text) w1; 
     Text t2 = (Text) w2; 
     String[] t1Items = t1.toString().split(" "); //probably it's a " " 
     String[] t2Items = t2.toString().split(" "); 
     String t1Value = t1Items[1]; 
     String t2Value = t2Items[1]; 
     int comp = t2Value.compareTo(t1Value); // We compare using "real" value part of our synthetic key in Descending order 

     return comp; 

    } 
} 

您可以设置自定义的比较如下:job.setSortComparatorClass(LogDescComparator.class);

作业的减速应该什么都不做。但是,如果我们不设置缩减器,则映射器键的排序将不会完成(我们需要这样做)。因此,您需要将IdentityReducer设置为第二个MR作业的Reducer,以便不减少但仍然确保映射器的合成键按照我们指定的方式排序。

+1

非常感谢您的详细解答。这真的很有帮助! – Searene

+0

@MarkZar不客气:) –