2016-07-05 2 views
15

약 5000 개의 행과 950 개의 열이있는 csv 파일이 있습니다. 우선은 DataFrame에로드 :Apache Spark : 문자열 열 인덱싱을 시도 할 때 StackOverflowError가 발생합니다.

val data = sqlContext.read 
    .format(csvFormat) 
    .option("header", "true") 
    .option("inferSchema", "true") 
    .load(file) 
    .cache() 

을 그 후 나는 그들에게 모든 문자열 열

val featuresToIndex = data.schema 
    .filter(_.dataType == StringType) 
    .map(field => field.name) 

검색 및 인덱싱 할. 이를 위해 나는 각 문자열 열

val stringIndexers = featuresToIndex.map(colName => 
    new StringIndexer() 
    .setInputCol(colName) 
    .setOutputCol(colName + "Indexed")) 

에 대한 인덱서를 작성하고 파이프 라인

val pipeline = new Pipeline().setStages(stringIndexers.toArray) 

를 생성하지만이 파이프 라인

val indexedDf = pipeline.fit(data).transform(data) 

내 초기 dataframe을 변환 할 때 나는 StackOverflowError가

16/07/05 16:55:12 INFO DAGScheduler: Job 4 finished: countByValue at StringIndexer.scala:86, took 7.882774 s 
Exception in thread "main" java.lang.StackOverflowError 
at scala.collection.immutable.Set$Set1.contains(Set.scala:84) 
at scala.collection.immutable.Set$Set1.$plus(Set.scala:86) 
at scala.collection.immutable.Set$Set1.$plus(Set.scala:81) 
at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:22) 
at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:20) 
at scala.collection.generic.Growable$class.loop$1(Growable.scala:53) 
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:57) 
at scala.collection.mutable.SetBuilder.$plus$plus$eq(SetBuilder.scala:20) 
at scala.collection.TraversableLike$class.to(TraversableLike.scala:590) 
at scala.collection.AbstractTraversable.to(Traversable.scala:104) 
at scala.collection.TraversableOnce$class.toSet(TraversableOnce.scala:304) 
at scala.collection.AbstractTraversable.toSet(Traversable.scala:104) 
at org.apache.spark.sql.catalyst.trees.TreeNode.containsChild$lzycompute(TreeNode.scala:86) 
at org.apache.spark.sql.catalyst.trees.TreeNode.containsChild(TreeNode.scala:86) 
at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:280) 
at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) 
... 

내가 뭘 잘못하고 있니? 감사합니다. .

+2

전체 예외 추적을 제공 할 수 있습니까? – sebszyller

+0

어떤 버전의 JDK를 사용하고 있습니까? –

+0

jdk 1.8.0_60 및 1.8.0_101을 시도했습니다. 전체 추적 http://pastebin.com/g9MsNtDp – Evilnef

답변

2

내가 해결책의 종류를 찾은 것처럼 보입니다 - 스파크 2.0을 사용하십시오. 이전에는 1.6.2를 사용했습니다. 문제가 발생한 당시의 최신 버전이었습니다. 2.0의 미리보기 버전을 사용하려고했지만 문제가 다시 발생했습니다.

-3

Java의 StackOverflowError Java 응용 프로그램에서 함수 호출을 호출하면 호출 스택에 스택 프레임이 할당됩니다. 스택 프레임은 호출 된 메소드의 매개 변수, 로컬 매개 변수 및 메소드의 리턴 주소를 포함합니다. 반환 주소는 호출 된 메서드가 반환 된 후 프로그램 실행이 계속되는 실행 지점을 나타냅니다. 새로운 스택 프레임을위한 공간이 없으면 JVM (Java Virtual Machine)에 의해 StackOverflowError가 발생합니다. Java 응용 프로그램의 스택을 완전히 소모 할 수있는 가장 일반적인 경우는 재귀입니다. 재귀에서는 메서드가 실행되는 동안 자체를 호출합니다. 재귀는 강력한 범용 프로그래밍 기술로 간주되지만 StackOverflowError를 피하기 위해주의해서 사용해야합니다.

가능한 해결책은 입니다. 1. 기본적으로 스파크는 메모리 만 RDD 직렬화를 사용합니다. 디스크 지속성 옵션으로 시도하십시오.

2. 드라이버 옵션에 -Xss5m과 같은 것을 추가하여 드라이버의 JVM 스택 크기를 늘리려고 시도하십시오. 당신이 data.schema

의 열 유형을 확인하는 경우 일부 재귀가 일어나고있는 가능성이 --driver - 자바 옵션 "-Xss 억"

파일 및 전체 예외 추적 공유 가능한 경우.

3

아마도 모든 스택 프레임을 유지하기에 충분한 메모리가 없을 것입니다. 나는 훈련 된 RandomForestModel과 비슷한 것을 경험한다. 내게는 작동 해결 방법은 추가 매개 변수 내 드라이버 응용 프로그램 (즉, 웹 서비스의) 실행하는 것입니다 :

-XX:ThreadStackSize=81920 -Dspark.executor.extraJavaOptions='-XX:ThreadStackSize=81920' 
+0

실제로 같은 문제에 직면하고 있습니다. 기본 스택 크기를 어떻게 알 수 있습니까? 게다가, 나는 그것이 드라이버가 아니라 Executor를위한 스택 크기를 증가시키는 것을 보았습니다, 맞습니까? –

+0

@ h.z. 두 사람 모두가 함께 일하기 때문에 두 사람 모두를위한 것입니다. ThreadStackSize는 드라이버 용입니다. executor 용은 executor.extraJavaOptions에서 시작됩니다. 크기를 측정 할 수 있는지 확실하지 않습니다. 작동하기 시작할 때까지 광산을 증가 시켰습니다. 더 큰 데이터 세트의 경우 여전히 실패 할 것으로 생각합니다. – evgenii

관련 문제