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.