簡體   English   中英

當所有內存設置都設置為巨大時,rdd.collect()中的java.lang.OutOfMemoryError

[英]java.lang.OutOfMemoryError in rdd.collect() when all memory setting are set to huge

我使用spark-submit運行以下python腳本,

r = rdd.map(list).groupBy(lambda x: x[0]).map(lambda x: x[1]).map(list)
r_labeled = r.map(f_0).flatMap(f_1)
r_labeled.map(lambda x: x[3]).collect()

它會收到java.lang.OutOfMemoryError,特別是在最后一行的collect()操作上,

java.lang.OutOfMemoryError
    at java.io.ByteArrayOutputStream.hugeCapacity(ByteArrayOutputStream.java:123)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:117)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at org.apache.spark.util.ByteBufferOutputStream.write(ByteBufferOutputStream.scala:41)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1877)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1786)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1189)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:43)
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:383)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
17/11/08 08:27:31 ERROR SparkUncaughtExceptionHandler: Uncaught exception in thread Thread[Executor task launch worker for task 6,5,main]
java.lang.OutOfMemoryError
    at java.io.ByteArrayOutputStream.hugeCapacity(ByteArrayOutputStream.java:123)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:117)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at org.apache.spark.util.ByteBufferOutputStream.write(ByteBufferOutputStream.scala:41)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1877)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1786)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1189)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:43)
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:383)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
17/11/08 08:27:31 INFO SparkContext: Invoking stop() from shutdown hook
17/11/08 08:27:31 WARN TaskSetManager: Lost task 0.0 in stage 9.0 (TID 6, localhost, executor driver): java.lang.OutOfMemoryError
    at java.io.ByteArrayOutputStream.hugeCapacity(ByteArrayOutputStream.java:123)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:117)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at org.apache.spark.util.ByteBufferOutputStream.write(ByteBufferOutputStream.scala:41)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1877)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1786)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1189)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:43)
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:383)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

該消息顯示OutOfMemoryError,但沒有其他內容。 是關於堆,垃圾回收還是其他? 我不知道。

無論如何,我試圖將有關內存的所有內容配置為巨大的價值。

spark.driver.maxResultSize = 0 # no limit
spark.driver.memory = 150g
spark.executor.memory = 150g
spark.worker.memory = 150g

(並且服務器具有157g的物理內存。)

仍然存在相同的錯誤。

然后我稍微減少了輸入數據,每次代碼都能完美傳遞。 實際上,collect()獲得的數據約為1.8g,遠小於物理15g內存。

現在,我確定該錯誤與代碼無關,並且物理內存沒有限制。 就像輸入數據的大小有一個閾值,傳遞該閾值將導致內存不足錯誤。

那么,如何解除這個閾值,以便在沒有內存錯誤的情況下處理更大的輸入數據? 有設置嗎?

謝謝。

==========跟進============

根據這個 ,這個錯誤是與Java序列化和MAP轉型的大對象。 我在代碼中確實使用了大對象。 想知道如何使Java Serializer容納大對象。

首先,只有在調用collect方法時才會遇到問題,這才有意義。 Spark很懶。 因此,在將數據發送到驅動程序(收集,減少,計數...)或磁盤(寫入,保存...)之前,它什么都不做。

然后,您似乎在執行程序上遇到了內存不足的異常。 我從堆棧跟蹤中了解到,您的groupBy正在創建一個數組,該數組的大小超過了已定義的容量(根據容量,Integer.MAX_VALUE-5)。 給定密鑰在您的數據集中是否可能出現超過20億次的出現?

無論如何,我不確定您要做什么,但是如果可以的話,請嘗試通過減少操作來替換groupBy,以減少對內存的壓力。

最終,盡管每個人只有150克,但您給了駕駛員和每個執行者150克。 我不知道您的情況是誰得到的。 嘗試合理地分享您的記憶,並告訴我們會發生什么。

希望這可以幫助。

暫無
暫無

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

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