Spark java.lang.OutOfMemoryError: พื้นที่ Java heap


228

คลัสเตอร์ของฉัน: 1 ต้นแบบ 11 ทาสแต่ละโหนดมีหน่วยความจำ 6 GB

การตั้งค่าของฉัน:

spark.executor.memory=4g, Dspark.akka.frameSize=512

นี่คือปัญหา:

ก่อนอื่นฉันอ่านข้อมูล (2.19 GB) จาก HDFS ถึง RDD:

val imageBundleRDD = sc.newAPIHadoopFile(...)

ประการที่สองทำอะไรกับ RDD นี้:

val res = imageBundleRDD.map(data => {
                               val desPoints = threeDReconstruction(data._2, bg)
                                 (data._1, desPoints)
                             })

สุดท้ายส่งออกไปยัง HDFS:

res.saveAsNewAPIHadoopFile(...)

เมื่อฉันรันโปรแกรมมันจะแสดง:

.....
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:24 as TID 33 on executor 9: Salve7.Hadoop (NODE_LOCAL)
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:24 as 30618515 bytes in 210 ms
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:36 as TID 34 on executor 2: Salve11.Hadoop (NODE_LOCAL)
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:36 as 30618515 bytes in 449 ms
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Starting task 1.0:32 as TID 35 on executor 7: Salve4.Hadoop (NODE_LOCAL)
Uncaught error from thread [spark-akka.actor.default-dispatcher-3] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[spark]
java.lang.OutOfMemoryError: Java heap space

มีงานมากเกินไป?

PS : ทุกอย่างก็โอเคเมื่อข้อมูลอินพุตมีค่าประมาณ 225 MB

ฉันจะแก้ปัญหานี้ได้อย่างไร


วิ่งประกายอย่างไร มันมาจากคอนโซลหรือไม่ หรือคุณใช้สคริปต์การปรับใช้ใด
— Tombart

ฉันใช้ sbt เพื่อคอมไพล์และรันแอพของฉัน แพคเกจ sbt แล้ว SBT ทำงาน ฉันใช้โปรแกรมเดียวกันบน hadoop เมื่อเดือนที่แล้วและฉันพบปัญหาเดียวกันของ OutOfMemoryError แต่ใน hadoop สามารถแก้ไขได้อย่างง่ายดายโดยเพิ่มมูลค่าของ mapred.child.java.opts จาก Xmx200m เป็น Xmx400m spark มีการตั้งค่า jvm ใด ๆ สำหรับงานหรือไม่ฉันสงสัยว่า spark.executor.memory มีความหมายเหมือนกันเช่น mapred.child.java.opts ใน hadoop ในโปรแกรมของฉัน spark.executor.memory ได้รับการตั้งค่าให้มีขนาดใหญ่กว่า Xmx400m ใน hadoop 4 กรัม ขอบคุณ ~
— hequn8128

คุณพูดถึงสามขั้นตอนเดียวที่คุณทำหรือไม่? ขนาดของ dataa ที่สร้างโดยอะไร (data._1, desPoints) - สิ่งนี้ควรพอดีกับหน่วยความจำถ้าข้อมูลนี้ถูกสับแล้วไปยังอีกขั้น
— Arnon Rotem-Gal-Oz

1
การกำหนดค่าหน่วยความจำสำหรับไดรเวอร์คืออะไร? ตรวจสอบว่าเซิร์ฟเวอร์ใดได้รับข้อผิดพลาดหน่วยความจำไม่เพียงพอ มันเป็นไดรเวอร์หรือหนึ่งในผู้บริหาร
— RanP

ดูที่นี่คุณสมบัติการกำหนดค่าทั้งหมด: spark.apache.org/docs/2.1.0/configuration.html
— Naramsim

คำตอบ:


364

ฉันมีคำแนะนำเล็กน้อย:

  • ถ้าโหนดของคุณมีการกำหนดให้มีได้สูงสุด 6g สำหรับ Spark (และกำลังจะออกน้อยสำหรับกระบวนการอื่น ๆ ) จากนั้นใช้ 6g มากกว่า spark.executor.memory=6g4g, ตรวจสอบให้แน่ใจว่าคุณใช้หน่วยความจำให้มากที่สุดโดยการตรวจสอบ UI (ซึ่งจะบอกว่าคุณใช้หน่วยความจำเท่าใด )
  • ลองใช้พาร์ติชันเพิ่มเติมคุณควรมี 2 - 4 ต่อ CPU IME การเพิ่มจำนวนพาร์ติชันมักเป็นวิธีที่ง่ายที่สุดในการทำให้โปรแกรมมีเสถียรภาพมากขึ้น (และบ่อยครั้งขึ้น) สำหรับข้อมูลจำนวนมากคุณอาจต้องใช้วิธีมากกว่า 4 ต่อซีพียูฉันต้องใช้พาร์ติชั่น 8000 พาร์ติชันในบางกรณี!
  • ลดส่วนของหน่วยความจำที่สงวนไว้สำหรับแคชspark.storage.memoryFractionใช้ หากคุณไม่ได้ใช้cache()หรือpersistในรหัสของคุณนี่อาจเป็น 0 ได้ค่าเริ่มต้นคือ 0.6 ซึ่งหมายความว่าคุณจะได้รับหน่วยความจำ 0.4 * 4g สำหรับกองของคุณเท่านั้น IME การลด mem frac มักทำให้ OOM หายไป อัปเดต:จากประกายไฟ 1.6 เห็นได้ชัดว่าเราไม่จำเป็นต้องเล่นกับค่าเหล่านี้อีกต่อไปประกายไฟจะกำหนดค่าเหล่านั้นโดยอัตโนมัติ
  • คล้ายกับข้างต้น แต่การสับเปลี่ยนส่วนหน่วยความจำ หากงานของคุณไม่ต้องการหน่วยความจำแบบสุ่มมากนักให้ตั้งค่าไว้ที่ค่าต่ำกว่า (ซึ่งอาจทำให้ตัวสับของคุณหกลงดิสก์ซึ่งอาจมีผลต่อความเร็วอย่างรุนแรง) บางครั้งเมื่อมีการสลับสับเปลี่ยนที่เป็น OOM คุณต้องทำในทางตรงกันข้ามเช่นตั้งค่าเป็นสิ่งที่มีขนาดใหญ่เช่น 0.8 หรือทำให้แน่ใจว่าคุณอนุญาตให้ shuffles ของคุณหกลงดิสก์ได้ (เป็นค่าเริ่มต้นตั้งแต่ 1.0.0)
  • ระวังการรั่วไหลของหน่วยความจำสิ่งเหล่านี้มักเกิดจากการปิดวัตถุที่คุณไม่ต้องการใน lambdas โดยไม่ตั้งใจ วิธีการวินิจฉัยคือมองหา "งานต่อเนื่องเป็น XXX ไบต์" ในบันทึกถ้า XXX มีขนาดใหญ่กว่าสองสามพัน k หรือมากกว่า MB คุณอาจมีหน่วยความจำรั่ว ดูhttps://stackoverflow.com/a/25270600/1586965
  • ที่เกี่ยวข้องกับข้างต้น; ใช้ตัวแปรออกอากาศหากคุณต้องการวัตถุขนาดใหญ่
  • หากคุณกำลังแคช RDDs ขนาดใหญ่และสามารถเสียสละเวลาในการเข้าถึงบางคนคิดว่า serialising RDD http://spark.apache.org/docs/latest/tuning.html#serialized-rdd-storage หรือแม้แต่ทำการแคชไว้ในดิสก์ (ซึ่งบางครั้งก็ไม่ได้เลวร้ายหากใช้ SSD)
  • ( ขั้นสูง ) ที่เกี่ยวข้องกับข้างต้นหลีกเลี่ยงStringและโครงสร้างที่ซ้อนกันมาก (เช่นMapและคลาสเคสที่ซ้อนกัน) หากเป็นไปได้ลองใช้ชนิดและดัชนีดั้งเดิมเท่านั้นไม่ใช่ทั้งหมดโดยเฉพาะอย่างยิ่งหากคุณคาดหวังว่าจะซ้ำซ้อนมาก เลือกWrappedArrayโครงสร้างที่ซ้อนกันทุกครั้งที่ทำได้ หรือแม้กระทั่งแผ่ออกเป็นอันดับของคุณเอง - คุณจะมีข้อมูลมากที่สุดเกี่ยวกับวิธีการได้อย่างมีประสิทธิภาพกลับข้อมูลของคุณลงในไบต์ใช้มัน !
  • ( bit hacky ) อีกครั้งเมื่อทำการแคชลองใช้ a Datasetเพื่อแคชโครงสร้างของคุณเพราะมันจะใช้การจัดลำดับที่มีประสิทธิภาพมากขึ้น สิ่งนี้ควรถูกพิจารณาว่าเป็นแฮ็คเมื่อเปรียบเทียบกับสัญลักษณ์แสดงหัวข้อก่อนหน้า การสร้างความรู้เกี่ยวกับโดเมนของคุณใน algo / serialization สามารถลด memory / cache-space ลงได้ 100x หรือ 1,000x ในขณะที่สิ่งที่Datasetจะให้คือ 2x - 5x ในหน่วยความจำและการบีบอัด 10 เท่า (parquet) บนดิสก์

http://spark.apache.org/docs/1.2.1/configuration.html

แก้ไข: (ดังนั้นฉันสามารถ google ตัวเองง่ายขึ้น) ต่อไปนี้เป็นตัวบ่งชี้ถึงปัญหานี้:

java.lang.OutOfMemoryError : GC overhead limit exceeded

ขอบคุณสำหรับคำแนะนำของคุณ ~ ถ้าฉันตั้งค่า spark.executor.memory = 6g, spark จะมีปัญหา: "ตรวจสอบ UI คลัสเตอร์ของคุณเพื่อให้แน่ใจว่าคนงานได้รับการลงทะเบียนและมีหน่วยความจำเพียงพอ" การตั้งค่า spark.storage.memoryFraction เป็น 0.1 ไม่สามารถแก้ปัญหาได้เช่นกัน อาจมีปัญหาอยู่ในรหัสของฉันขอบคุณ!
— hequn8128

2
@samthebest นี่คือคำตอบที่ยอดเยี่ยม ฉันซาบซึ้งกับความช่วยเหลือในการบันทึกเพื่อค้นหารอยรั่วของหน่วยความจำ
— Myles Baker

1
สวัสดี @samthebest คุณระบุพาร์ติชั่นได้อย่างไร 8000 เนื่องจากฉันใช้ Spark sql ฉันสามารถระบุพาร์ติชันได้โดยใช้ spark.sql.shuffle.partitions ค่าเริ่มต้นคือ 200 ฉันควรตั้งค่าให้มากกว่านี้ฉันพยายามตั้งค่าเป็น 1,000 แต่ไม่ช่วยให้รับ OOM คุณทราบดีว่าอะไรเหมาะสม ค่าพาร์ติชั่นฉันมีข้อมูล 1 TB ที่ต้องทำการประมวลผลและเกี่ยวข้องกับกลุ่มโดยกลุ่มคำสั่ง กรุณาแนะนำ
— Umesh K

2
สวัสดี @ user449355 โปรดช่วยถามคำถามใหม่หน่อยได้ไหม? สำหรับความกลัวที่จะเริ่มหัวข้อกระทู้ยาว ๆ :) ถ้าคุณมีปัญหาคนอื่นน่าจะเป็นและคำถามจะช่วยให้ค้นหาได้ง่ายขึ้นสำหรับทุกคน
— samthebest

1
ถึงจุดแรกของคุณ @samthebest คุณไม่ควรใช้หน่วยความจำทั้งหมดspark.executor.memoryเพราะคุณต้องการหน่วยความจำจำนวนหนึ่งสำหรับค่าใช้จ่าย I / O หากคุณใช้ทั้งหมดมันจะทำให้โปรแกรมของคุณช้าลง ข้อยกเว้นนี้อาจเป็น Unix ซึ่งในกรณีนี้คุณมีพื้นที่สว็อป
— Hunle

58

ในการเพิ่มกรณีการใช้งานให้กับสิ่งนี้ซึ่งมักจะไม่กล่าวถึงฉันจะสร้างโซลูชันเมื่อส่งSparkแอปพลิเคชันผ่านspark-submitในโหมดท้องถิ่น

อ้างอิงจาก gitbook Mastering Apache SparkโดยJacek Laskowski :

คุณสามารถเรียกใช้ Spark ในโหมดโลคัล ในโหมดการปรับใช้ JVM เดี่ยวแบบไม่กระจายนี้ Spark จะวางไข่ส่วนประกอบการดำเนินการทั้งหมด - ไดรเวอร์ผู้ควบคุมการปฏิบัติการแบ็กเอนด์และมาสเตอร์ - ใน JVM เดียวกัน นี่เป็นโหมดเดียวที่ใช้ไดรเวอร์สำหรับการดำเนินการ

ดังนั้นหากคุณกำลังประสบOOMข้อผิดพลาดกับheapมันพอเพียงที่จะปรับมากกว่าdriver-memoryexecutor-memory

นี่คือตัวอย่าง:

spark-1.6.1/bin/spark-submit
  --class "MyClass"
  --driver-memory 12g
  --master local[*] 
  target/scala-2.10/simple-project_2.10-1.0.jar 

เปอร์เซ็นต์ที่เราควรพิจารณาสำหรับหน่วยความจำไดรเวอร์ในโหมดสแตนด์อะโลน
— Yashwanth Kambala

@Brian, ในโหมด Local, หน่วยความจำไดรเวอร์จำเป็นต้องมีขนาดใหญ่กว่าขนาดข้อมูลอินพุตหรือไม่? เป็นไปได้หรือไม่ที่จะระบุจำนวนพาร์ติชันสำหรับชุดข้อมูลอินพุตดังนั้นงาน Spark สามารถจัดการกับชุดข้อมูลที่มีขนาดใหญ่กว่า RAM ที่มีอยู่ได้มากหรือไม่
— fuyi

19

คุณควรกำหนดการตั้งค่าหน่วยความจำ offHeap ตามที่แสดงด้านล่าง:

val spark = SparkSession
     .builder()
     .master("local[*]")
     .config("spark.executor.memory", "70g")
     .config("spark.driver.memory", "50g")
     .config("spark.memory.offHeap.enabled",true)
     .config("spark.memory.offHeap.size","16g")   
     .appName("sampleCodeForReference")
     .getOrCreate()

ให้หน่วยความจำไดรเวอร์และหน่วยความจำของผู้ปฏิบัติการตามความพร้อมใช้งาน RAM ของเครื่อง คุณสามารถเพิ่มขนาด offHeap ถ้าคุณยังคงเผชิญปัญหา


เพิ่มการตั้งค่า offHeap ช่วย
— kennyut

2
การตั้งค่าหน่วยความจำไดรเวอร์ในรหัสของคุณจะไม่ทำงานอ่านเอกสาร spark สำหรับเรื่องนี้: คุณสมบัติ Spark ส่วนใหญ่สามารถแบ่งออกเป็นสองประเภท: หนึ่งเกี่ยวข้องกับการปรับใช้เช่น "spark.driver.memory", "spark.executor.instances", คุณสมบัติชนิดนี้อาจไม่ได้รับผลกระทบเมื่อตั้งค่าโดยทางโปรแกรมผ่าน SparkConf ในรันไทม์หรือลักษณะการทำงานขึ้นอยู่กับตัวจัดการคลัสเตอร์และโหมดการปรับใช้ที่คุณเลือกดังนั้นจึงแนะนำให้ตั้งค่าผ่านไฟล์กำหนดค่าหรือตัวเลือกบรรทัดคำสั่ง spark-submit
— Abdulhafeth

1
คำตอบที่ดีที่สุด! ปัญหาของฉันคือ Spark ไม่ได้ติดตั้งที่โหนดหลักฉันเพิ่งใช้ PySpark เพื่อเชื่อมต่อกับ HDFS และได้รับข้อผิดพลาดเดียวกัน การใช้การconfigแก้ไขปัญหา
— Mikhail_Sam

ฉันเพิ่งเพิ่มการกำหนดค่าโดยใช้คำสั่ง spark-submit เพื่อแก้ไขปัญหาขนาดฮีพ ขอบคุณ
— Pritam Sadhukhan

16

คุณควรเพิ่มหน่วยความจำไดรเวอร์ ในโฟลเดอร์ $ SPARK_HOME / conf ของคุณคุณควรค้นหาไฟล์spark-defaults.confแก้ไขและตั้งค่าspark.driver.memory 4000mตามหน่วยความจำในต้นแบบของคุณ นี่คือสิ่งที่แก้ไขปัญหาสำหรับฉันและทุกอย่างทำงานได้อย่างราบรื่น


ร้อยละเท่าใดของ mem ที่จะได้รับการจัดสรรในแบบสแตนด์อะโลน
— Yashwanth Kambala

14

ดูที่สคริปต์เริ่มต้นที่มีการตั้งค่าขนาดฮีพของ Java ไว้ที่นั่นดูเหมือนว่าคุณไม่ได้ตั้งค่านี้ก่อนที่จะเรียกใช้ Spark worker

# Set SPARK_MEM if it isn't already set since we also use it for this process
SPARK_MEM=${SPARK_MEM:-512m}
export SPARK_MEM

# Set JAVA_OPTS to be able to load native libraries and to set heap size
JAVA_OPTS="$OUR_JAVA_OPTS"
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=$SPARK_LIBRARY_PATH"
JAVA_OPTS="$JAVA_OPTS -Xms$SPARK_MEM -Xmx$SPARK_MEM"

คุณสามารถค้นหาเอกสารในการปรับใช้สคริปต์ที่นี่


ขอบคุณ ~ ฉันจะลองอีกครั้ง จาก spark ui จะแสดงหน่วยความจำของผู้ดำเนินการทุกคนคือ 4096 ดังนั้นการตั้งค่าจึงเปิดใช้งานใช่ไหม
— hequn8128

เห็นคำตอบของคุณในขณะที่ฉันกำลังเผชิญกับปัญหาที่คล้ายกัน ( stackoverflow.com/questions/34762432/… ) ดูลิงค์ที่คุณให้ไว้ดูเหมือนว่าการตั้งค่า Xms / Xmx ไม่มีอยู่อีกต่อไปคุณบอกได้ไหมว่าเพราะอะไร
— Seffy

เนื้อหาที่สคริปต์ที่ลิงก์โดยstart up scriptsมีการเปลี่ยนแปลงไปอย่างน่าเสียดาย ไม่มีตัวเลือกดังกล่าวตั้งแต่วันที่ 2019-12-19
— David Groomes

7

ฉันได้รับความเดือดร้อนจากปัญหานี้มากมายเราใช้การจัดสรรทรัพยากรแบบไดนามิกและฉันคิดว่ามันจะใช้ทรัพยากรคลัสเตอร์ของฉันเพื่อให้เหมาะกับแอปพลิเคชันที่สุด

แต่ความจริงก็คือการจัดสรรทรัพยากรแบบไดนามิกไม่ได้ตั้งค่าหน่วยความจำไดรเวอร์และทำให้มันเป็นค่าเริ่มต้นของมันคือ 1g

ฉันแก้ไขมันโดยการตั้งค่า spark.driver.memory ให้เป็นตัวเลขที่เหมาะสมกับหน่วยความจำของคนขับ (สำหรับ 32GB ram ฉันตั้งค่าเป็น 18gb)

คุณสามารถตั้งค่าโดยใช้คำสั่ง spark submit ดังนี้

spark-submit --conf spark.driver.memory=18gb ....cont

หมายเหตุสำคัญมากคุณสมบัตินี้จะไม่ถูกนำมาพิจารณาหากคุณตั้งค่าจากรหัสตามเอกสารประกอบ spark:

คุณสมบัติ Spark ส่วนใหญ่สามารถแบ่งออกเป็นสองชนิด: หนึ่งเกี่ยวข้องกับการปรับใช้เช่น "spark.driver.memory", "spark.executor.instances" คุณสมบัติชนิดนี้อาจไม่ได้รับผลกระทบเมื่อตั้งโปรแกรมโดยใช้ SparkConf ในรันไทม์หรือ พฤติกรรมจะขึ้นอยู่กับตัวจัดการคลัสเตอร์และโหมดการปรับใช้ที่คุณเลือกดังนั้นจึงแนะนำให้ตั้งค่าผ่านไฟล์กำหนดค่าหรือตัวเลือกบรรทัดคำสั่ง spark-submit ส่วนใหญ่เกี่ยวข้องกับการควบคุมรันไทม์ Spark เช่น "spark.task.maxFailures" คุณสมบัติประเภทนี้สามารถตั้งค่าได้ทั้งสองทาง


2
คุณควรใช้ --conf spark.driver.memory = 18g
— merenptah

5

การพูดในวงกว้างหน่วยความจำ Executionor JVM สามารถแบ่งออกเป็นสองส่วน หน่วยความจำ Spark และหน่วยความจำผู้ใช้ นี้จะถูกควบคุมโดยคุณสมบัติspark.memory.fraction- ค่าอยู่ระหว่าง 0 และ 1 spark.memory.fractionเมื่อทำงานกับภาพหรือทำประมวลผลหน่วยความจำอย่างเข้มข้นในการใช้งานจุดประกายให้พิจารณาลดลง นี่จะทำให้หน่วยความจำเพิ่มเติมพร้อมใช้งานสำหรับแอปพลิเคชันของคุณ Spark สามารถหกได้ดังนั้นจึงยังทำงานได้โดยใช้หน่วยความจำน้อยกว่า

ส่วนที่สองของปัญหาคือการแบ่งงาน ถ้าเป็นไปได้แบ่งพาร์ติชันข้อมูลของคุณเป็นกลุ่มย่อย ๆ ข้อมูลขนาดเล็กอาจต้องการหน่วยความจำน้อย แต่ถ้าเป็นไปไม่ได้คุณจะต้องเสียสละเพื่อความทรงจำ โดยทั่วไปแล้วผู้บริหารเดียวจะทำงานหลายคอร์ หน่วยความจำทั้งหมดของตัวจัดการต้องเพียงพอที่จะรองรับความต้องการหน่วยความจำของงานที่เกิดขึ้นพร้อมกันทั้งหมด หากการเพิ่มหน่วยความจำตัวประมวลผลไม่ใช่ตัวเลือกคุณสามารถลดแกนประมวลผลแต่ละตัวเพื่อให้แต่ละงานได้รับหน่วยความจำมากขึ้น ทดสอบกับตัวประมวลผลหลัก 1 ตัวซึ่งมีหน่วยความจำที่ใหญ่ที่สุดเท่าที่คุณสามารถให้ได้


5

คุณทิ้งบันทึก gc หลักของคุณหรือไม่ ดังนั้นฉันพบปัญหาที่คล้ายกันและพบ SPARK_DRIVER_MEMORY ตั้ง Xap heap เท่านั้น ขนาดฮีปเริ่มต้นจะยังคงอยู่ที่ 1G และขนาดฮีปจะไม่ปรับเพิ่มเป็นฮีป Xmx

ผ่าน "--conf" spark.driver.extraJavaOptions = -Xms20g "ช่วยแก้ปัญหาของฉัน

ps aux | grep java และคุณจะเห็นบันทึกการติดตาม: =

24501 30.7 1.7 41782944 2318184 pts / 0 Sl + 18:49 0:33 / usr / java / ล่าสุด / bin / java -cp / opt / spark / conf /: / opt / spark / jars / * -Xmx30g -Xms20g


3

ตำแหน่งที่ตั้งขนาดฮีปหน่วยความจำ (อย่างน้อยใน spark-1.0.0) อยู่ใน conf / spark-env ตัวแปรที่เกี่ยวข้องคือSPARK_EXECUTOR_MEMORY& SPARK_DRIVER_MEMORY. เอกสารเพิ่มเติมอยู่ในคู่มือการปรับใช้

นอกจากนี้อย่าลืมคัดลอกไฟล์การตั้งค่าไปยังโหนดทาสทั้งหมด


4
คุณจะรู้ว่าเป็นที่หนึ่งในการปรับระหว่างSPARK_EXECUTOR_MEMORY& SPARK_DRIVER_MEMORY?
— Hunle

13
คือสิ่งที่ผิดพลาดจะบอกให้คุณเพิ่มขึ้นSPARK_EXECUTOR_MEMORYและสิ่งที่ผิดพลาดจะบอกให้คุณสามารถเพิ่มSPARK_DRIVER_MEMORY?
— Hunle

2

ฉันมีข้อเสนอแนะเล็กน้อยสำหรับข้อผิดพลาดดังกล่าวข้างต้น

●ตรวจสอบหน่วยความจำตัวประมวลผลที่กำหนดให้เป็นตัวเรียกใช้งานอาจต้องจัดการกับพาร์ติชันที่ต้องการหน่วยความจำมากกว่าสิ่งที่กำหนดไว้

●ลองดูว่ามีการสลับสับเปลี่ยนเพิ่มเติมหรือไม่เนื่องจากการสับเป็นการดำเนินการที่มีราคาแพงเนื่องจากเกี่ยวข้องกับดิสก์ I / O, การจัดลำดับข้อมูลและ I / O เครือข่าย

●ใช้ Broadcast Joins

●หลีกเลี่ยงการใช้ groupByKeys และลองแทนที่ด้วย ReduceByKey

●หลีกเลี่ยงการใช้วัตถุ Java ขนาดใหญ่ไม่ว่าจะเกิดการสับที่ใด


ขอโทษที่จี้คนอื่นจากแบบสอบถาม แต่จะใช้ findByKey แทน groupBy ได้อย่างไร?
— Somil Aseeja

1

จากความเข้าใจของฉันเกี่ยวกับรหัสที่ให้ไว้ด้านบนมันจะโหลดไฟล์และทำการแม็พและบันทึกกลับ ไม่มีการดำเนินการที่ต้องสลับ นอกจากนี้ยังไม่มีการดำเนินการที่ต้องใช้ข้อมูลที่จะนำไปยังไดรเวอร์ดังนั้นการปรับแต่งสิ่งที่เกี่ยวข้องกับการสับเปลี่ยนหรือไดรเวอร์อาจไม่มีผลกระทบ ไดรเวอร์มีปัญหาเมื่อมีงานมากเกินไป แต่นี่เป็นเพียงจนถึงรุ่น 2.0.2 spark อาจมีสองสิ่งที่ผิดปกติ

  • มีตัวจัดการเพียงหนึ่งหรือสองตัวเท่านั้น เพิ่มจำนวนตัวเรียกใช้งานเพื่อให้สามารถจัดสรรไปยังทาสที่แตกต่างกัน หากคุณกำลังใช้เส้นด้ายจำเป็นต้องเปลี่ยนการตั้งค่า num-executors หรือหากคุณกำลังใช้ Spark แบบสแตนด์อโลนคุณจำเป็นต้องปรับแต่ง num cores ต่อผู้ปฏิบัติการและ spark max cores conf ในตัวประมวลผลแบบสแตนด์อโลน = คอร์สูงสุด / แกนต่อหนึ่งตัวดำเนินการ
  • จำนวนพาร์ติชันมีน้อยมากหรืออาจเป็นเพียงพาร์ติชันเดียว ดังนั้นหากสิ่งนี้ต่ำแม้ว่าเราจะมีหลายคอร์หลายตัวประมวลผลก็จะไม่ได้รับความช่วยเหลือมากนักเนื่องจากการขนานจะขึ้นอยู่กับจำนวนพาร์ติชัน ดังนั้นเพิ่มพาร์ติชันโดยทำ imageBundleRDD.repartition (11)

0

การกำหนดค่าที่แน่นอนเหล่านี้ช่วยแก้ไขปัญหาได้

spark-submit --conf spark.yarn.maxAppAttempts=2 --executor-memory 10g --num-executors 50 --driver-memory 12g
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.