我使用Hadoop总订单分区器和随机抽样器作为输入采样器。
但是当我增加我的从属节点并将任务减少到8时,我得到以下错误:
Caused by: java.io.IOException: Split points are out of order
我不知道这个错误的原因。
如何在inputsampler.randomsampler
功能上设置三个参数的数量?
答案 0 :(得分:1)
两个可能的问题
您可以通过下载分区文件并检查其内容来诊断此问题。如果已设置,则分区文件的值为total.order.partitioner.path
,否则为_partition.lst
。如果您的密钥是文本,则可以运行hdfs dfs -text path_to_partition_file | less
来查看。这也适用于其他关键类型,但我还没有尝试过。
如果分区文件中有重复的行,则表示您有重复的键,否则您可能使用了错误的比较器。
我最好的猜测是你的密钥是如此不平衡,以至于分区之间的记录均匀划分会生成具有相同分割点的分区。
要解决此问题,您有以下几种选择:
a
,a
,b
,c
,c
,c
,{{1 },d
作为分裂点然后你有9个减少器(8个分裂点)和3个最大重复数。所以,使用3个减速器(3 = floor(9/3))并且如果你的采样是好的,你可能最终会得到正确的分割点。为了完全稳定,你需要能够重新运行分区步骤,如果它有重复的条目,那么你可以防止偶尔过度采样不平衡键,但是复杂程度,您可以查看下一个解决方案。e
)并使用num_non_duplicates
缩减器。具有重复键的减速器将比其他减速器具有更多的工作并且运行更长时间。如果reduce操作是可交换和关联的,您可以通过使用组合器来缓解这种情况。确保在num_non_duplicates+1
的调用和使用mapred.output.key.comparator.class
writePartitionFile
设置相同
TotalOrderPartitioner
错误消息来自代码:
Split points are out of order
行 RawComparator<K> comparator =
(RawComparator<K>) job.getOutputKeyComparator();
for (int i = 0; i < splitPoints.length - 1; ++i) {
if (comparator.compare(splitPoints[i], splitPoints[i+1]) >= 0) {
throw new IOException("Split points are out of order");
}
}
表示如果一对分割点相同或无序,则会被拒绝。
1或2个reducer永远不会产生此错误,因为不能有超过1个分割点,并且循环永远不会执行。
答案 1 :(得分:0)
您确定要生成足够的密钥吗? 来自javadoc:TotalOrderPartitioner
输入文件必须使用相同的比较器进行排序并包含
JobContextImpl.getNumReduceTasks() - 1 keys.