Spark 2.0.1 java.lang.NegativeArraySizeException

bes*_*sil 1 java apache-spark apache-spark-2.0

我开始玩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());
Run Code Online (Sandbox Code Playgroud)

产生一个

 java.lang.NegativeArraySizeException
Run Code Online (Sandbox Code Playgroud)

和JVM(1.8)检测到的致命错误.

使用数据集api处理数据(即,选择,依靠信息对象)可以正常工作.

如何在数据集和RDD之间切换?

Ram*_*ram 5

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

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

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

System.out.println(infos.rdd().count());
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

非常大的对象图

参考限制

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

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

  Kryo kryo = new Kryo();
  kryo.setReferences(false);
Run Code Online (Sandbox Code Playgroud)

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

Spark文档说明了这一点

spark.kryo.referenceTracking 默认值 true

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