我正在使用 Hadoop 分析非常不均匀的数据分布。有些键有数千个值,但大多数只有一个。例如,与 IP 地址相关联的网络流量将有许多数据包与一些健谈的 IP 相关联,而只有少数与大多数 IP 相关联。另一种说法是基尼指数非常高。
为了有效地处理这个问题,每个reducer 应该获得一些高音量键或大量低音量键,以便获得大致均匀的负载。如果我正在编写分区过程,我知道该怎么做:我将获取keys
映射器生成的(包括所有重复键)的排序列表以及减速器的数量,N
并将拆分放在
split[i] = keys[floor(i*len(keys)/N)]
Reduceri
将获得k
诸如split[i] <= k < split[i+1]
for0 <= i < N-1
和split[i] <= k
for 的键i == N-1
。
我愿意用 Java 编写自己的分区器,但Partitioner<KEY,VALUE>类似乎一次只能访问一个键值记录,而不是整个列表。我知道 Hadoop 对映射器生成的记录进行排序,所以这个列表必须存在于某个地方。它可能分布在几个分区器节点中,在这种情况下,我会在其中一个子列表上执行拆分过程,并以某种方式将结果传达给所有其他分区器节点。(假设选择的分区节点看到一个随机子集,结果仍然是近似负载平衡的。) 有谁知道排序的键列表存储在哪里,以及如何访问它?
我不想编写两个 map-reduce 作业,一个是查找拆分,另一个是实际使用它们,因为这看起来很浪费。(映射器必须做两次相同的工作。)这似乎是一个普遍的问题:不均匀分布很常见。