2016-11-11 137 views
0

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

也许我失去了一些东西,希望有人能帮助。

这些指令

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处理数据(即选择计数信息对象)可以正常工作。

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

回答

1

一般来说这个错误来了when an application tries to create an array with negative size.看下面的例子。

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

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

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

引起你可以审查该代码中的情况下,其negetively初始化,通过打印完整的堆栈跟踪。

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) 

注:使用情况的一个与 apache的火花沿着使用Kryo系列化...当它可以发生/解决方法是像下面...

Very large object graphs

参考限制

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

针对此问题的解决方法是禁用KRYO的基准跟踪,如下所示 :

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

或者在spark-default.confspark.kryo.refferenceTrackingEnabled = false属性或sparkConf对象,如果您希望通过编程设置..

Spark docs says that

spark.kryo.referenceTracking默认值true

是否与KRYO,这是必要的,如果你的对象图有循环和效率 有用的串行数据 当跟踪引用同一个对象,如果他们包含相同的 对象的多个副本。如果知道这不是 的情况,可以禁用以提高性能。

+0

谢谢你的回答。问题是spark.read()和其他指令是库调用,即我刚刚使用了库,没有定制代码,除了Info.class。 – besil

+0

你可以粘贴更多的细节,如你的JSON,完整的错误堆栈跟踪和信息模型对象等... –