java – 在Hadoop Map-Reduce中,任何类在排序之后和分区之前是否会看到整个键列表?

我正在使用Hadoop来分析非常不均匀的数据分布.有些键有数千个值,但大多数只有一个.例如,与IP地址相关联的网络流量将具有与少量健谈IP相关联的许多分组以及具有大多数IP的少数分组.另一种说法是 Gini index非常高.

为了有效地处理这个问题,每个reducer应该获得一些高音量键或许多低音量键,以便获得大致均匀的负载.如果我正在编写分区进程,我知道如何执行此操作:我将获取由映射器生成的键的排序列表(包括所有重复键)以及减少器的数量N和放置拆分

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

减速器我将获得密钥k,使得split [i]< = k< split [i 1] for 0< = i<对于i == N-1,N-1和split [i]< = k. 我愿意用Java编写自己的分区器,但Partitioner<KEY,VALUE>类似乎一次只能访问一个键值记录,而不是整个列表.我知道Hadoop会对映射器生成的记录进行排序,因此该列表必须存在于某处.它可能分布在多个分区节点之间,在这种情况下,我会在其中一个子列表上执行拆分过程,并以某种方式将结果传递给所有其他分区节点. (假设所选分区器节点看到一个随机化子集,结果仍然是近似负载平衡的.)有没有人知道存储密钥的排序列表的位置,以及如何访问它?

我不想编写两个map-reduce作业,一个用于查找拆分,另一个用于实际使用它们,因为这看起来很浪费. (地图制作者必须做两次相同的工作.)这似乎是一个普遍的问题:不均匀的分布很常见.

解决方法

我一直在考虑这个问题.如果有人强迫我,这是我会采取的高级方法.

>除了用于解决业务问题的映射器逻辑之外,还要编写一些逻辑来收集分区器中需要的任何统计信息,以便以平衡的方式分配键值对.当然,每个映射器只会看到一些数据.
>每个映射器都可以找到其任务ID,并使用该ID在指定的hdfs文件夹中构建唯一的文件名,以保存收集的统计信息.将此文件写入在任务结束时运行的cleanup()方法中.
>在分区程序中使用延迟初始化来读取指定hdfs目录中的所有文件.这将为您提供在映射器阶段收集的所有统计信息.从那里开始,您将实现正确分区数据所需的任何分区逻辑.

这一切都假设在所有映射器完成之前不会调用分区器,但这是迄今为止我能够做到的最好的.

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...