1

我使用 Hadoop 全序分区器和随机采样器作为输入采样器。

但是当我增加我的从节点并将任务减少到 8 个时,我收到以下错误:

Caused by: java.io.IOException: Split points are out of order

我不知道这个错误的原因。

如何设置inputsampler.randomsampler函数的三个参数的数量?

4

2 回答 2

1

两个可能的问题

  • 你有重复的钥匙
  • 您正在为输入采样器和运行总订单分区器的任务使用不同的比较器

您可以通过下载分区文件并检查其内容来诊断此问题。分区文件是total.order.partitioner.path设置或_partition.lst其他方式的值。如果你的键是文本,你可以跑hdfs dfs -text path_to_partition_file | less过去看看。这也可能适用于其他密钥类型,但我还没有尝试过。

如果分区文件中有重复的行,则说明您有重复的键,否则您可能使用了错误的比较器。

怎么修

重复键

我最好的猜测是您的键是如此不平衡,以至于分区之间的记录均匀划分会生成具有相同分割点的分区。

要解决此问题,您有多种选择:

  • 选择一个值用作更好地区分输入的键(可能不可能,但如果可以的话会更好)
  • 使用更少的分区和reducer(不像下一个解决方案那样可扩展或确定,但实现起来更简单,特别是如果你只有几个重复项)。将原始分区数除以最大重复条目数。(例如,如果您的分区键文件列出:a, a, b, c, c, c, d,e作为分割点,那么你有 9 个减速器(8 个分割点)和 3 个最大重复项。所以,使用 3 个减速器(3=floor(9/3)),如果你的采样很好,你最终可能会得到正确的分割点。为了完全稳定,如果它有重复的条目,您需要能够重新运行分区步骤,这样您就可以防止偶尔对不平衡键进行过度采样,但在这种复杂程度下,您不妨看看下一个解决方案。
  • 读取分区文件,在没有重复条目的情况下重写它,计算条目数(调用它num_non_duplicates)并使用num_non_duplicates+1减速器。具有重复键的减速器将比其他减速器做更多的工作并且运行时间更长。如果 reduce 操作是可交换和关联的,您可以通过使用组合器来缓解这种情况。

使用错误的比较器

确保您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");
    }
  }

这条线comparator.compare(splitPoints[i], splitPoints[i+1]) >= 0意味着如果一对分割点相同或无序,则它们将被拒绝。

1 或 2 个 reducer 永远不会产生此错误,因为分割点不能超过 1 个,并且循环永远不会执行。

于 2017-06-19T16:55:29.627 回答
0

你确定你生成了足够的密钥吗?来自 javadoc:TotalOrderPartitioner

输入文件必须使用相同的比较器进行排序并包含

JobContextImpl.getNumReduceTasks() - 1 keys.
于 2016-10-08T15:14:25.427 回答