4

我开始玩 Spark 2.0.1。新的数据集 API 非常干净,但我遇到了非常简单的操作问题。

也许我错过了一些东西,希望有人能提供帮助。

这些说明

SparkConf conf = new SparkConf().setAppName("myapp").setMaster("local[*]");
SparkSession spark = SparkSession
        .builder()
        .config(conf)
        .getOrCreate();

Dataset<Info> infos = spark.read().json("data.json").as(Encoders.bean(Info.class));

System.out.println(infos.rdd().count());

产生一个

 java.lang.NegativeArraySizeException

以及 JVM (1.8) 检测到的致命错误。

使用数据集 api 处理数据(即选择、依靠 infos 对象)工作正常。

如何在 Dataset 和 RDD 之间切换?

4

1 回答 1

7

通常,当应用程序尝试创建具有负大小的数组时会出现此错误。见下面的例子。

它的一般 java 错误。在你的情况下,我怀疑这是由

 Dataset<Info> infos = spark.read().json("data.json").as(Encoders.bean(Info.class));

System.out.println(infos.rdd().count());

您可以通过打印完整的堆栈跟踪来查看此代码在哪种情况下,它的负初始化。

import java.util.*;
import java.io.*;
public class Stacktest
{
public static void main(String args[])throws IOException
{
int c[]=new int[-2];
Scanner in=new Scanner(new InputStreamReader(System.in));
int b=in.nextInt();
int a[]=new int[b];
}
}


output:

-2
Exception in thread "main" java.lang.NegativeArraySizeException
        at Stacktest.main(Stacktest.java:10)

注意: 其中一个用例是Kryo与 apache spark 一起使用序列化......当它可能发生/修复时,如下所示......

非常大的对象图

参考限值

Kryo将引用存储在基于int数组的映射中。由于 Java 数组索引仅限于Integer.MAX_VALUE,因此序列化大型(> 10 亿)对象可能会导致 java.lang.NegativeArraySizeException.

此问题的解决方法是禁用 Kryo 的参考跟踪,如下所示:

  Kryo kryo = new Kryo();
  kryo.setReferences(false);

或者像spark.kryo.refferenceTrackingEnabled= falseinspark-default.confsparkConfobject 这样的属性,如果你想以编程方式设置它..

Spark 文档说

spark.kryo.referenceTracking 默认值true

是否在使用 Kryo 序列化数据时跟踪对同一对象的引用,如果您的对象图有循环,这是必要的,如果它们包含同一对象的多个副本,则对提高效率很有用。如果您知道情况并非如此,可以禁用以提高性能。

于 2016-11-11T20:27:45.043 回答