簡體   English   中英

小文本數據上的Spark OutOfMemory錯誤

[英]Spark OutOfMemory error on small text data

我正在努力實現一種算法,並在本地節點上的Spark(Scala接口)中的中型數據上對其進行測試。 我從非常簡單的處理開始,盡管我非常確定數據不足以使此類錯誤合理,但我正在獲取java.lang.OutOfMemoryError: Java heap space 這是最小的破壞代碼:

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkContext, SparkConf}

val conf = new SparkConf()
  .setMaster("local[4]")
  .setAppName("AdultProcessing")
  .set("spark.executor.memory", "1g")
val sc = new SparkContext(conf)

val dataFile = "data/census/processed/census-income.data"
val censusData: RDD[String] = sc.textFile(dataFile, 4)
val censusDataPreprocessed = censusData.map { row =>
  val separators: Array[Char] = ":,".toCharArray
  row.split(separators)
}

val res = censusDataPreprocessed.collect()

我使用的數據是未經壓縮的經典人口普查數據 這是100MB,近20萬行。 我的機器上的內存量應足夠:

nietaki@xebab$ free -tm
             total       used       free     shared    buffers     cached
Mem:         15495      12565       2929          0        645       5608
-/+ buffers/cache:       6311       9183
Swap:         3858          0       3858
Total:       19354      12566       6788

每個虛擬節點的數據文件塊都小於30MB,而我正在執行的唯一處理是將行字符串拆分為50個以下項的數組。 我簡直不敢相信此操作會耗盡內存。

在嘗試調試情況時,我發現將節點數減少到1,或者將SparkContext.textFile()minPartitions參數從4增加到例如8可以解決這種情況,但這並不能解決我的問題任何明智的。

我正在使用Spark 1.0.0和Scala 2.10.4。 我直接從sbt啟動項目: sbt run -Xmx2g -Xms2g

JVM內存不足。 Spark在JVM上運行。

我建議您使用探查器檢查堆,以找出記錄所使用的實際內存。 在我的情況下,它們的大小是“靜止”大小的2倍,並且它們是原始類型和字符串的組合。

在您的情況下,字符串尤其容易吃。 "" (空字符串)的長度約為40個字節-較長的字符串可以抵消結構的成本。 [1]

將先前資源中的表應用於數據:

line: String = 73, Not in universe, 0, 0, High school graduate, 0, Not in universe, Widowed, Not in universe or children, Not in universe, White, All other, Female, Not in universe, Not in universe, Not in labor force, 0, 0, 0, Nonfiler, Not in universe, Not in universe, Other Rel 18+ ever marr not in subfamily, Other relative of householder, 1700.09, ?, ?, ?, Not in universe under 1 year old, ?, 0, Not in universe, United-States, United-States, United-States, Native- Born in the United States, 0, Not in universe, 2, 0, 95, - 50000.

line.size
Int = 523
def size(s:String) = s.size/4*8+40
line.split(",.").map(w=>size(w)).sum
Int = 2432

因此,由於所有這些小字符串,您的內存中數據大約是“靜態”大小的5倍。 盡管如此,該數據的200k行仍約占500MB。 這可能表明您的執行器以默認值512MB運行。 嘗試將“ spark.executor.memory”設置為更高的值,但也要考慮大於8Gb的堆大小,以方便使用Spark。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM