ทำความเข้าใจ “ห้องครัว” ใน Spark: ไขปริศนา Out Of Memory (OOM) ให้งานประมวลผลราบรื่น

ทำความเข้าใจ “ห้องครัว” ใน Spark: ไขปริศนา Out Of Memory (OOM) ให้งานประมวลผลราบรื่น

เคยเจอปัญหา Spark Job ล่มเพราะ หน่วยความจำไม่พอ หรือที่เรียกว่า OOM (Out Of Memory) ไหม? มันเหมือนกับการที่เชฟพยายามจะทำอาหารหลายอย่างพร้อมกันในห้องครัวเล็ก ๆ จนวัตถุดิบล้นพื้นที่ไปหมด การทำความเข้าใจโครงสร้างหน่วยความจำของ Spark จึงเป็นสิ่งสำคัญที่จะช่วยให้งานประมวลผลข้อมูลขนาดใหญ่ของคุณดำเนินไปได้อย่างราบรื่น

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

RAM คือวัตถุดิบทั้งหมดที่มีอยู่ในตู้กับข้าวและตู้เย็น

CPU คือมือของเชฟที่กำลังปรุงอาหาร

Disk ก็เป็นเหมือนห้องเก็บของที่ไว้เก็บวัตถุดิบที่ไม่จำเป็นต้องใช้ทันที หรือของที่ปรุงเสร็จแล้วแต่ยังไม่ถึงเวลาเสิร์ฟ

สำรวจส่วนต่าง ๆ ของหน่วยความจำ Spark

หน่วยความจำใน Spark นั้นแบ่งออกเป็นส่วนหลัก ๆ เหมือนกับพื้นที่ใช้งานในห้องครัวที่ถูกจัดสรรไว้ชัดเจน

พื้นที่ Spark Memory

นี่คือพื้นที่ทำงานหลักของเชฟ (Spark) ที่ใช้สำหรับงานประมวลผลและจัดเก็บข้อมูล เป็นสัดส่วนที่คำนวณจาก JVM Heap ลบด้วยหน่วยความจำสำรอง แล้วคูณด้วยค่า spark.memory.fraction

ภายใน Spark Memory ยังแบ่งย่อยอีกสองส่วนสำคัญ:

  • หน่วยความจำสำหรับดำเนินการ (Execution Memory): เปรียบเหมือน เคาน์เตอร์ทำอาหาร เป็นพื้นที่ที่เชฟใช้ในการเตรียมวัตถุดิบ ผสม หรือหั่น นั่นคือใช้สำหรับเก็บข้อมูลชั่วคราวระหว่างการดำเนินการ เช่น การจัดเรียง (sort), การรวมข้อมูล (join), การสับเปลี่ยนข้อมูล (shuffle) หรือการรวมกลุ่ม (aggregation) หากพื้นที่นี้ไม่พอ ข้อมูลก็จะถูกนำไปพักไว้บนดิสก์ (spill to disk)

  • หน่วยความจำสำหรับจัดเก็บ (Storage Memory): เหมือน ตู้เย็นหรือตู้กับข้าว สำหรับเก็บวัตถุดิบที่เตรียมไว้แล้ว หรืออาหารที่ปรุงเสร็จแล้วแต่ยังไม่เสิร์ฟ ซึ่งก็คือ Cached RDDs หรือ DataFrames หากพื้นที่นี้เต็ม ข้อมูลที่ถูกใช้งานน้อยที่สุดจะถูกนำออกไปเพื่อเพิ่มพื้นที่ให้ข้อมูลใหม่

พื้นที่ User Memory

นี่คือ พื้นที่ส่วนตัวของเชฟ ที่เก็บข้าวของส่วนตัว หรือวัตถุดิบลับเฉพาะที่เชฟใช้เอง ไม่ใช่ส่วนที่ Spark จัดการโดยตรง เช่น ตัวแปรต่าง ๆ ในโค้ด หรือโครงสร้างข้อมูลที่ไม่เกี่ยวข้องกับ Spark โดยตรง พื้นที่นี้คำนวณจากส่วนที่เหลือของ JVM Heap หลังจากหัก Reserved Memory และ Spark Memory ออกไป

พื้นที่ Reserved Memory

เปรียบเสมือน ห้องเก็บอุปกรณ์ฉุกเฉินหรือระบบสาธารณูปโภค ที่จำเป็นต่อการทำงานของครัว เป็นหน่วยความจำขนาดเล็กประมาณ 300MB ที่ถูกจองไว้สำหรับกระบวนการภายในที่สำคัญของ Spark และไม่สามารถปรับแต่งได้

พื้นที่ Off-Heap Memory (กรณีพิเศษ)

เป็นเหมือน เตาย่างบาร์บีคิวนอกบ้าน หรือตู้เก็บของเสริมที่ไม่ได้อยู่ในห้องครัวหลัก แต่สามารถใช้งานได้ พื้นที่นี้ไม่ได้อยู่ใน JVM Heap ทำให้สามารถเก็บข้อมูลขนาดใหญ่ได้ดีกว่า และจัดการโดยระบบปฏิบัติการโดยตรง มักใช้กับฟีเจอร์อย่าง Tungsten เพื่อเพิ่มประสิทธิภาพในการจัดการข้อมูล

จัดการปัญหา OOM ให้ Spark ทำงานได้เต็มประสิทธิภาพ

เมื่อเข้าใจองค์ประกอบต่าง ๆ แล้ว การแก้ไขปัญหา OOM ก็จะง่ายขึ้น เหมือนการปรับปรุงการทำงานในครัว

  • เมื่อมีงานมากเกินไปสำหรับหนึ่งห้องครัว: เหมือนเชฟคนเดียวต้องทำอาหารหลายจานพร้อมกัน

    • วิธีแก้: ลดจำนวนเชฟต่อห้องครัวด้วยการปรับ spark.executor.cores ลง หรือเพิ่มขนาดห้องครัวและวัตถุดิบด้วยการเพิ่ม spark.executor.memory
  • ข้อมูลขนาดใหญ่ไหลเข้ามาพร้อมกัน: เหมือนวัตถุดิบจำนวนมหาศาลมาส่งพร้อมกัน

    • วิธีแก้: เพิ่มขนาดห้องครัว spark.executor.memory และปรับการแบ่งส่วนข้อมูล (partition) ด้วย spark.sql.shuffle.partitions ให้เหมาะสม เพื่อให้งานกระจายตัวได้ดีขึ้น
  • เก็บข้อมูลแคชมากเกินไป: เหมือนตู้เย็นเต็มไปด้วยของที่ปรุงไว้แล้วจนไม่มีที่เก็บวัตถุดิบใหม่

    • วิธีแก้: ทบทวนกลยุทธ์การแคชข้อมูล เพิ่ม spark.executor.memory หรือปรับ spark.memory.storageFraction
  • ข้อมูลกระจุกตัว (Data Skew): เหมือนวัตถุดิบทั้งหมดไปกองอยู่กับเชฟคนเดียว

    • วิธีแก้: แบ่งส่วนข้อมูลใหม่ (re-partition), ใช้เทคนิค salting หรือ broadcast ตารางขนาดเล็ก
  • UDF (User-Defined Function) หรือไลบรารีภายนอกใช้หน่วยความจำมาก: เหมือนเชฟนำอุปกรณ์ทำอาหารพิเศษที่กินไฟมากมาใช้

    • วิธีแก้: วิเคราะห์การใช้หน่วยความจำของ UDF เหล่านั้น และเพิ่ม spark.executor.memory

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