MapReduce(二级)排序/过滤 - 如何?

时间:2011-03-31 20:11:40

标签: java sorting hadoop mapreduce

我有一个聊天室webapp的不同“区域”的时间戳值(并发用户)的日志文件,格式为“Timestamp; Zone; Value”。对于每个区域,每天每分钟存在一个值。

对于每个区域,我想列出每天的最大值,按此最大值排序desc

所以,

的输入文件
#timestamp; zone; value
2011-01-01 00:00:00; 1; 10
2011-01-01 00:00:00; 2; 22
2011-01-01 00:01:00; 1; 11
2011-01-01 00:01:00; 2; 21

2011-01-02 00:00:00; 1; 12
2011-01-02 00:00:00; 2; 20

应为区域1生成:

2011-01-02    12
2011-01-01    11

和第2区:

2011-01-01    22
2011-01-02    20

我该如何处理?恕我直言,我需要一个以上的M / R步骤。

到目前为止我实施的是:

  • 收集文本键“YYYY-MM-DD / Zone”和IntWritable值“value”的映射器,
  • 一个减速器,用于标识每个键的最大值(即每个区域每天)。

这会产生类似

的文件
2011-01-01/1    11
2011-01-01/2    22
2011-01-02/1    12
2011-01-02/2    20

这是第二次M / R步骤的输入吗?如果是这样,我会把什么作为关键和价值?

我已经研究过“Hadoop - The Definitive Guide”中的“Secondary Sort”示例,但我不确定是否以及如何在此处应用它。

是否可以将M / R分成几个输出文件(每个区域一个)?

更新 在考虑之后,我会尝试这个:

  • 使密钥成为zone-id和value的组合(使用IntPair?)
  • 编写自定义KeyComparator和GroupComparator

3 个答案:

答案 0 :(得分:7)

您可以使用二级排序只使用一个MR。以下是步骤

  1. 将键定义为zone,yyyy-mm-dd和值为区域的连接:yyyy-mm-dd:value正如我将解释的那样,您甚至不需要从映射器中发出任何值。 NullWritable对于值

  2. 来说已经足够了
  3. 实现密钥比较器,使得密钥的区域:yyyy-mm-dd部分按升序排序,值部分按降序排序。这将确保对于给定区域的所有键:yyyy-mm-dd,组中的第一个键将具有最高值

  4. 根据键的区域和日期部分,即区域:yyyy-mm-dd,定义复合键的分区器和分组比较器。

  5. 在您的reducer输入中,您将获得一个密钥组的第一个密钥,该密钥组将包含区域,日期和该区域的最大值,日期组合。 reducer输入的值部分是NullWritable列表,可以忽略。

答案 1 :(得分:0)

我不知道你需要两个map / reduce步骤 - 你当然可以用一个,只是你的结果是列表而不是单个条目。否则,是的,您将按区域拆分,然后按日期拆分。

我可能会按区域将其拆分,然后让每个区域按天返回最高元素列表,因为此时减少非常简单。要真正从另一个地图/缩小步骤中获益,您必须拥有一个非常大的数据集和许多机器才能分开 - 此时我可能会减少整个键。

答案 2 :(得分:0)

使用复合键模式解决Map reduce中的二级排序,因此您可以创建类似(ZoneId,TImeStamp)的键,并且在reducer中,您将首先在时区上进行迭代,然后在时间戳上进行迭代,以便您可以轻松地评估每天的最大值。 / p>