2015-11-27 18 views
5

Tôi đang sử dụng máy đơn Spark độc lập, với bộ nhớ 128G và 32 lõi. Sau đây là các cài đặt tôi nghĩ có liên quan đến vấn đề của tôi:Ứng dụng Spark - Java.lang.OutOfMemoryError: Vùng heap Java

spark.storage.memoryFraction  0.35 
spark.default.parallelism  50 
spark.sql.shuffle.partitions  50 

Tôi có ứng dụng Spark trong đó có vòng lặp cho 1000 thiết bị. Với mỗi vòng lặp (thiết bị) nó chuẩn bị vector tính năng và sau đó gọi k-Means của MLLib. Tại vòng lặp thứ 25 đến 30 của vòng lặp (xử lý thiết bị từ 25 đến 30), nó chạy vào lỗi "Java.lang.OutOfMemoryError: khoảng trống Java".

Tôi đã thử bộ nhớLoại từ 0,7 đến 0,35, nhưng không hiệu quả. Tôi cũng đã thử song song/phân vùng đến 200 mà không có may mắn. Tùy chọn JVM là "-Xms25G -Xmx25G -XX: MaxPermSize = 512m". Kích thước dữ liệu của tôi chỉ khoảng 2G.

Đây là stack trace:

java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:2271) 
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118) 
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93) 
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.write(ObjectOutputStream.java:1841) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1533) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 
    at scala.collection.mutable.HashMap$$anonfun$writeObject$1.apply(HashMap.scala:138) 
    at scala.collection.mutable.HashMap$$anonfun$writeObject$1.apply(HashMap.scala:136) 
    at scala.collection.mutable.HashTable$class.foreachEntry(HashTable.scala:230) 
    at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:40) 
    at scala.collection.mutable.HashTable$class.serializeTo(HashTable.scala:125) 
    at scala.collection.mutable.HashMap.serializeTo(HashMap.scala:40) 
    at scala.collection.mutable.HashMap.writeObject(HashMap.scala:136) 
    at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 

Lúc đầu, các ứng dụng có vẻ tốt đẹp, nhưng sau khi nó chạy trong một thời gian và quy trình ngày càng nhiều thiết bị hơn, Java heap được chiếm dần và bộ nhớ không được phát hành bởi JVM. Cách chẩn đoán và khắc phục sự cố như vậy?

+0

Nó đang cố gắng tuần tự hóa dữ liệu, có thể là rất lớn về dữ liệu. Tôi đề nghị bạn tăng kích thước heap tối đa để nói 100 GB thay vì 25 GB. –

+0

Đang thử kích thước heap 100G ngay bây giờ. Cám ơn vì sự gợi ý. – wdz

+0

Bạn đã thử đặt spark.rdd.compress thành true? –

Trả lời

1

Bạn luôn có thể sử dụng các công cụ lược tả như visualVM. để theo dõi tăng trưởng bộ nhớ. Hy vọng bạn đang sử dụng JVM 64 bit chứ không phải JVM 32 bit. Quá trình 32 bit có thể chỉ sử dụng bộ nhớ 2GB, do đó, cài đặt bộ nhớ cơ bản sẽ không sử dụng được. Hy vọng điều này sẽ giúp

+0

Cảm ơn bạn đã giới thiệu visualVM. Tôi đang thử nó ngay bây giờ để theo dõi việc sử dụng bộ nhớ. BTW, tôi đang sử dụng JVM 64 bit. – wdz

0

Tùy chọn JVM không đủ để định cấu hình bộ nhớ Spark, bạn cũng cần đặt spark.driver.memory (đối với trình điều khiển, obv.) Và spark.executor.memory (đối với người lao động). Các giá trị này được đặt thành 1gb theo mặc định. See this thorough guide để biết thêm thông tin. Trên thực tế, tôi mong bạn đọc nó, có rất nhiều thứ ở đó và làm quen với nó chắc chắn sẽ trả lại sau này.

+0

Trong cài đặt của tôi, tôi có "spark.driver.memory 16G" và "spark.executor.memory 96G". Tôi thực sự đã đi qua tài liệu cấu hình Spark nhưng vẫn không thể khắc phục vấn đề OOM của tôi. Tôi đang thử visualVM ngay bây giờ để xem điều gì xảy ra trong heap. – wdz

2

Ngoài điều khiển và bộ nhớ Executor, sẽ đề nghị để thử các tùy chọn sau đây: -

  1. Đổi thành Kryo serialization - http://spark.apache.org/docs/latest/tuning.html#data-serialization
  2. Sử dụng MEMORY_AND_DISK_SER_2 cho RDD kiên trì.

Ngoài ra, sẽ tốt nếu bạn có thể đăng mã.

+0

Cảm ơn bạn đã đề xuất! Tôi đã sử dụng tuần tự hóa Kryo. Vì MEMORY_AND_DISK_SER_2 chậm hơn đáng kể so với MEMORY_ONLY nên tôi không muốn sử dụng trừ khi tôi không có lựa chọn nào khác. – wdz

+0

Tôi đồng ý nhưng Mục tiêu đề xuất "MEMORY_AND_DISK_SER_2" trước tiên phải đảm bảo rằng công việc của bạn ít nhất là hoàn thành. Điều này sẽ xác minh rằng logic của bạn là chính xác mặc dù không được tối ưu hóa, sau đó chúng tôi có thể điều chỉnh nó cho hiệu suất tốt hơn để nó thực hiện hoàn toàn trong bộ nhớ. – Sumit

+0

Tôi sẽ thử tùy chọn MEMORY_AND_DISK_SER_2. – wdz

Các vấn đề liên quan