【问题标题】:MapReduce (secondary) sorting / filtering - how?MapReduce(二级)排序/过滤 - 如何?
【发布时间】:2011-03-31 20:11:40
【问题描述】:

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

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

所以,一个输入文件

#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 值“值”的映射器,并且
  • 识别每个键(即每天每个区域)的最大值的缩减程序。

这会产生一个类似的文件

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”中的“二级排序”示例,但不确定是否以及如何在此处应用。

是否可以 M/R 到多个输出文件(每个区域一个)?

更新 想了想,我就试试这个:

  • 使键成为区域 ID 和值的组合(使用 IntPair?)
  • 编写自定义 KeyComparator 和 GroupComparator

【问题讨论】:

    标签: java sorting hadoop mapreduce


    【解决方案1】:

    您可以使用二级排序仅使用一个 MR 来完成此操作。以下是步骤

    1. 将键定义为区域、yyyy-mm-dd 的串联,并将值定义为 zone:yyyy-mm-dd:value 正如我将解释的,您甚至不需要从映射器发出任何值。 NullWritable 值够用了

    2. 实现键比较器,使得键的 zone:yyyy-mm-dd 部分按升序排列,而值部分按降序排列。这将确保对于给定区域的所有键:yyyy-mm-dd,组中的第一个键将具有最高值

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

    4. 在您的减速器输入中,您将获得一个键组的第一个键,其中将包含区域、日期和该区域、日期组合的最大值。 reducer输入的value部分会是一个NullWritable列表,可以忽略。

    【讨论】:

      【解决方案2】:

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

      我可能会按区域将其拆分,然后让每个区域按天返回一个最高元素的列表,因为那时减少将非常容易。要真正从另一个 map/reduction 步骤中获得好处,您必须拥有一个非常大的数据集和许多要拆分的机器——此时我可能会对整个 key 进行归约。

      【讨论】:

      • 不太清楚你的意思——你能解释一下 Mapper 和 Reducer 究竟会做什么吗?谢谢,t。
      • 嗯,当然。 map/reduce 是将工作拆分为可管理的独立块的问题。因此,您选择一个分隔区(例如,区域)并按区域拆分数据。这意味着每个进程都需要一个数据片——区域——并遍历数据。当它获得一个日期时,它会在本地地图中查找该日期的更高值;如果它没有找到,它会创建它。处理完所有数据后,它会返回一个带有区域的值 + 日期/值的映射。减少会将所有这些组合到地图中,其中键是区域,有效负载是日期/值的地图。
      • 好吧,只有几个区域,但每个区域的值在 100,000 个。 Mapper 会产生什么输出?
      • 你比我更了解你的数据——但会做的是让地图产生一对>。您的集群的大小可能允许您基于天而不是区域进行路由,这意味着反转:pair>.
      • 好的,假设映射器产生 >。减速器检查每个值是否是给定日期的最大值,并将其存储为新的最大值(如果它大于旧的最大值) - 到目前为止,它已被理解,类似于我描述的当前解决方案。但是,我如何实现 desc。每天按价值订购?和:(如何)每个reducer(每个区域一个)输出到一个单独的文件中?
      【解决方案3】:

      Map reduce 中的二次排序是通过复合键模式解决的,因此您可以创建 (ZoneId, TImeStamp) 之类的键,在 reducer 中,您将首先遍历时区,然后遍历时间戳,这样您就可以轻松评估每天的最大值。

      【讨论】:

        猜你喜欢
        • 2015-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-09
        • 2012-06-01
        相关资源
        最近更新 更多