我正在尝试为Hadoop设计一个映射器和还原器。我是Hadoop的新手,我对映射器和还原器如何适用于我的特定应用程序感到有点困惑。
我的映射器的输入是一个大型有向图的连通性。它是一个2列输入,其中每一行都是一个单独的边连通性。第一列是每个边的开始节点id,第二列是每个边的结束节点id。我试图将每个开始节点id的邻居数量输出到一个2列文本文件中,其中第一列按照开始节点id的增加顺序排序。
我的问题是:
(1)输入已经设置为每一行都是键值对,其中键是开始节点id,值是结束节点id。映射器会简单地读取每一行并将其写出来吗?这似乎是多余的。
(2)分选是否发生在映射器和减速器之间,或者分选实际上可以用减速器本身完成?
如果我的理解是正确的,你想计算一个键将有多少个不同的值。
简单地在映射器中发出输入键值对,然后在简化器中计算每个键的不同值(例如,通过将它们添加到集合并将集合大小作为简化器的值)是一种方法,但正如您所说,有点多余。
一般来说,您希望减少流量,因此您可能希望在混洗之前进行更多计算(是的,这是由Hadoop完成的)。
提高效率的两种简单方法是:
1)使用组合器,它将输出一组值,而不是单个值。这样,您将向还原器发送更少的键值对,并且,一些值可能会被跳过,因为它们已经在同一键的本地值集中。
2)使用映射端聚合。不要立即发出输入的键值对,而是将它们本地存储在映射器中(在内存中)的数据结构(例如,hashmap或multimap)中。键可以是映射输入键,值可以是迄今为止看到的该键的一组值。您遇到的每种类型都为该键添加了一个新值,您将其附加到此结构中。在每个映射器的末尾,您会发出此结构(或者将值转换为数组),来自close()方法(如果我记得名称)。
您可以使用关键字“组合器”和“地图端聚合”查找这两种方法。
键的全局排序有点棘手。同样,有两个基本选项,但不是很好:1)您使用单个还原器,但您不会从并行性中获得任何收益,2)您使用总顺序分区器,这需要一些额外的编码。
除此之外,您可能希望迁移到Spark以获得更直观、更高效的解决方案。