我是这里的hadoop新手。目前尚不清楚为什么我们需要能够在使用 hadoop mapreduce 时按键排序?在 map 阶段之后,我们需要将每个唯一键对应的数据分发到一定数量的 reducer。这可以在不需要排序的情况下完成吗?
2 回答
它就在那里,因为排序是对键进行分组的巧妙技巧。当然,如果您的工作或算法不需要任何密钥顺序,那么通过一些散列技巧进行分组会更快。
在 Hadoop 本身中,多年来已经有一个 JIRA 归档(来源)。Hadoop 之上的其他几个发行版已经具有这些功能,例如 Hanborq(他们称之为避免排序)。(来源)
对于您的实际问题(为什么),MapReduce 本质上是 Google 的一篇论文(来源),其中陈述了以下内容:
我们保证在给定的分区内,中间键/值对以递增的键顺序处理。这种排序保证可以很容易地为每个分区生成一个排序的输出文件,这在输出文件格式需要支持有效的 key 随机访问查找时很有用,或者输出的用户发现对数据进行排序很方便。
因此,支持排序更多是一个方便的决定,而不是本质上只允许排序对键进行分组。
如果我们考虑到 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->shoe_size
在这种情况下,我们可以利用 key grouping 的力量,将个人姓名和鞋码都发送到 SAME reduce 函数。
reducer(2) 将在此处收到 2 条记录:
ssn->名称,shoe_size
这里的想法是,在编写 map/reduce 作业时,您必须对输出的“元组”进行编码,以便它们可以在 reduce 阶段以有意义的方式连接在一起。在某些时候,任何分布式计算环境都可能需要组合在不同节点中计算的记录。Keys 为我们提供了一种方便且可扩展的方法来执行此操作。
所以 - 我们保证 SAME 密钥进入 SAME reducer 功能的事实证实,该特定社会安全号码的每个 reducer 将接收与该号码关联的所有数据,允许我们加入和输出包括 ssn 的数据记录,名字,鞋码。
结论
如果不按密钥分发,以这种方式连接数据将需要涉及某种中间数据存储/缓存的复杂逻辑。Hadoop 使用熟悉的范式简单概括和抽象了从并行计算中“连接”数据结果的常见需求:键和值。