java—在hadoop map reduce中,是否有任何类在排序之后和分区之前看到整个键列表?

dnph8jn4  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(722)

我使用hadoop来分析非常不均匀的数据分布。有些键有数千个值,但大多数键只有一个值。例如,与ip地址相关联的网络流量将有许多与少数健谈ip相关联的数据包,而只有少数与大多数ip相关联。另一种说法是,基尼指数非常高。
为了有效地处理这个问题,每个reducer要么得到几个高音量键,要么得到很多低音量键,这样就可以得到大致均匀的负载。我知道如果我正在编写分区进程,我将如何做到这一点:我将获取 keys (包括所有重复键)以及还原器的数量 N 把劈叉放在

split[i] = keys[floor(i*len(keys)/N)]

减速机 i 会拿到钥匙吗 k 以至于 split[i] <= k < split[i+1] 为了 0 <= i < N-1 以及 split[i] <= k 为了 i == N-1 .
我愿意用java编写自己的partitioner,但是partitioner<key,value>类似乎一次只能访问一个键值记录,而不是整个列表。我知道hadoop对Map程序生成的记录进行排序,所以这个列表肯定存在于某个地方。它可能分布在几个分区器节点之间,在这种情况下,我将对其中一个子列表执行拆分过程,并以某种方式将结果传递给所有其他分区器节点(假设所选的分区器节点看到一个随机化的子集,结果仍然是大致负载平衡的。)有人知道排序的键列表存储在哪里,以及如何访问它吗?
我不想写两个map reduce作业,一个是查找拆分,另一个是实际使用拆分,因为这看起来很浪费(Map绘制者将不得不做同样的工作两次。)这似乎是一个普遍的问题:不均匀分布是很常见的。

gmxoilav

gmxoilav1#

据我所知,mr处理中没有一个地方所有的密钥都存在。更重要的是,不能保证一台机器可以存储这些数据。我认为这个问题在目前的mr框架下并没有理想的解决方案。我这么认为是因为要得到理想的解决方案——我们必须等待最后一个Map器的结束,然后才能用这些知识分析密钥分布和参数化分区器。
这种方法将显著地使系统复杂化并提高延迟。
我认为很好的近似方法是对数据进行随机抽样,得到密钥分布的概念,然后让partitioner根据它工作。
据我所知,terasort实现正在做一些非常类似的事情:http://sortbenchmark.org/yahoohadoop.pdf

vwoqyblh

vwoqyblh2#

我也一直在考虑这个问题。如果有人强迫我,我会采取这种高层次的方法。
除了解决业务问题所需的Map器逻辑之外,还要编写一些逻辑代码来收集分区器中所需的任何统计信息,以便以平衡的方式分发键值对。当然,每个Map器只能看到部分数据。
每个Map器都可以找到它的任务id,并使用该id在指定的hdfs文件夹中构建一个唯一的文件名,以保存收集到的统计信息。在任务结束时运行的cleanup()方法中写出此文件。
在分区器中使用延迟初始化来读取指定hdfs目录中的所有文件。这将获得在mapper阶段收集的所有统计信息。从这里开始,您就可以实现正确划分数据所需的任何划分逻辑。
这一切都假设在所有Map程序完成之前不会调用分区器,但这是迄今为止我所能做的最好的事情。

相关问题