【发布时间】:2012-08-14 00:01:56
【问题描述】:
我是这里的 hadoop 新手。目前尚不清楚为什么我们需要能够在使用 hadoop mapreduce 时按键排序?在 map 阶段之后,我们需要将每个唯一键对应的数据分发到一定数量的 reducer。这可以在不需要排序的情况下完成吗?
【问题讨论】:
我是这里的 hadoop 新手。目前尚不清楚为什么我们需要能够在使用 hadoop mapreduce 时按键排序?在 map 阶段之后,我们需要将每个唯一键对应的数据分发到一定数量的 reducer。这可以在不需要排序的情况下完成吗?
【问题讨论】:
它就在那里,因为排序是对键进行分组的巧妙技巧。当然,如果您的工作或算法不需要任何密钥顺序,那么通过一些散列技巧进行分组会更快。
多年来,在 Hadoop 本身中,已经有一个 JIRA 归档(source)。 Hadoop 之上的其他几个发行版已经具有这些功能,例如 Hanborq(他们称之为避免排序)。 (source)
对于您的实际问题(为什么),MapReduce 本质上是来自 Google (source) 的一篇论文,其中陈述了以下内容:
我们保证在给定的分区内,中间键/值 对以递增的密钥顺序处理。此订购保证 可以很容易地为每个分区生成一个排序的输出文件, 当输出文件格式需要支持高效随机时很有用 通过键访问查找,或输出的用户发现它很方便 对数据进行排序。
因此,支持排序更多是一个方便的决定,但并不是天生就只允许排序对键进行分组。
【讨论】:
如果我们考虑到 hadoop DISTRIBUTES 通过向不同的机器发送不同的密钥来为您处理的事实,则最好理解“按密钥排序”。这个想法的基本(简化)版本是这样的:
The reducer which a (k,v) pair is sent to = k.hashCode()%num_of_machines.
因此,例如,如果我的密钥的哈希码是 10,并且我有 2 台机器,那么密钥将被发送到机器 #0。
因此,密钥将(首先)为我们提供了一种分配计算的简单方法。
除了简化计算分布之外,键还为我们提供了一种将不同数据文件中的记录连接到单个集群中的方法。例如,这就是我们如何做 word_count 之类的事情。
事实上,如果你发现你不需要密钥 --- 你可能也不需要 hadoop !
经典例子(字数):
在 hadoop“字数统计”示例中,我们发出带有值的键(一个键 = 一个词)(该词在一段文本中出现的 # 次)。这允许 SINGLE reduce 函数接收 SINGLE 单词,从而添加所有看到的时间,从而创建准确的单词计数。
因此,键的聚合允许“映射”阶段独立地分布在多台机器上。在没有将键聚合到同一个 reducer 的情况下,在字数统计示例中,我们可能会获得给定单词的多个字数,因为无法保证单个 reducer 会接收来自所有文件的所有字数。
另一个例子:
现在...假设我们有社会安全号码作为 id,我们想要输出个人数据的聚合。假设我们有 2 个大文件。
ssn->名字
ssn->鞋码
在这种情况下,我们可以利用键分组的力量,将个人姓名和鞋码都发送到 SAME reduce 函数。
reducer(2) 将在此处接收 2 条记录:
ssn->名称,鞋码
这里的想法是,在编写 map/reduce 作业时,您必须对输出的“元组”进行编码,以便它们可以在 reduce 阶段以有意义的方式连接在一起。在某些时候,任何分布式计算环境都可能需要组合在不同节点中计算的记录。 Keys 为我们提供了一种方便且可扩展的方法来执行此操作。
所以 - 我们保证 SAME 密钥进入 SAME reducer 函数这一事实证实,该特定社会安全号码的每个 reducer 将接收与该号码关联的所有数据,允许我们加入和输出数据记录包括 ssn、姓名和鞋码。
结论
如果不按密钥分发,以这种方式连接数据将需要涉及某种中间数据存储/缓存的极其复杂的逻辑。 Hadoop 通过使用熟悉的范式:键和值,简单地概括和抽象了从并行计算中“连接”数据结果的常见需求。
【讨论】: