Capstone: ประกอบทุกอย่างเข้าด้วยกัน
Lab สุดท้าย — ไม่มีโค้ดให้ก็อปปี้แล้ว ต้องออกแบบเอง เลือกโปรเจกต์หนึ่งข้อ ประยุกต์ใช้เทคนิคจาก Lab 0-5 ทั้งหมดเข้าด้วยกัน พร้อมแผนที่ว่าจะไปต่อจากจุดนี้อย่างไร
1เลือกโปรเจกต์หนึ่งข้อ
ต่อยอดจาก orders.csv ใน Lab 2 — เพิ่มข้อมูลจำลองให้ใหญ่ขึ้น (หลักหมื่นแถว) แล้วสร้าง pipeline ที่: (1) ingest ข้อมูลดิบแบบ schema-on-read (บทที่ 8), (2) ทำ data wrangling, (3) train โมเดลทำนายว่าลูกค้าคนไหนมีแนวโน้ม churn (Lab 3), (4) เขียนผลลัพธ์เป็น Parquet
ต่อยอดจาก Lab 4 — สร้าง event generator ที่ส่งข้อมูลจำลอง (เช่น log การคลิกเว็บ) ผ่าน socket อย่างต่อเนื่อง แล้วทำ windowed aggregation หาสถิติ real-time (เช่น "5 หน้าเว็บที่มีคนดูมากสุดใน 1 นาทีล่าสุด") บันทึกผลลง memory table แล้วแสดงผลด้วย display() ใน notebook ทุก 10 วินาที
ต่อยอดจาก Lab 5 — สร้างกราฟเครือข่ายสังคมจำลองขนาดใหญ่กว่าเดิม (50-100 คน) รัน PageRank หา influencer, ใช้ Connected Components หากลุ่มย่อย, และใช้ motif finding หารูปแบบความสัมพันธ์ที่น่าสนใจ (เช่น "triangle of mutual friends")
ความท้าทายสูงสุด — เขียน batch pipeline (Lab 2) ที่ประมวลผลข้อมูลราย, streaming pipeline (Lab 4) ที่จับ event ใหม่แบบ real-time, และ ML model (Lab 3) ที่ train จากข้อมูล batch แล้วนำไปทำนายบน stream — จำลองสถาปัตยกรรมแบบ Facebook ที่กล่าวถึงในบทที่ 9 (บทวิชา Parallel Systems) แต่ใช้เครื่องมือจากวิชานี้แทน
2Checklist ก่อนเริ่ม
- อธิบายได้ว่าทำไมปัญหานี้ถึง "เป็น Big Data จริง" ตามกรอบ 4V ในบทที่ 1 — หรืออธิบายตรงไปตรงมาว่าจริง ๆ แล้วสเกลของปัญหาอาจไม่ต้องการ Spark เลยก็ได้ (เชื่อมโยงกับบทที่ 3 เรื่อง "grey area" ของ horizontal/vertical scaling)
- ใช้ DataFrame/SQL API อย่างน้อยหนึ่งจุด (Lab 2)
- มีขั้นตอนที่แสดงความเข้าใจเรื่อง schema/data quality (บทที่ 8)
- มีการวัดผลเชิงปริมาณ ไม่ใช่แค่ "ดูเหมือนทำงาน" (accuracy/AUC สำหรับ ML, throughput สำหรับ streaming)
- บันทึกผลลัพธ์ในรูปแบบที่ใช้ต่อได้ (Parquet, saved model)
3ไปต่อจากที่นี่: เครื่องมือและแพลตฟอร์มที่ควรรู้จัก
| หัวข้อ | ทำไมควรเรียนรู้ต่อ |
|---|---|
| Delta Lake / Apache Iceberg | เพิ่ม ACID transaction ให้กับ data lake (บทที่ 8) — ใช้งานจริงในองค์กรส่วนใหญ่ที่ทำ data engineering บน Spark |
| Managed Spark Platform | สภาพแวดล้อมที่ผู้ให้บริการช่วยดูแล Cluster เหมาะสำหรับเปรียบเทียบกับ Lab 0 ที่เราตั้งระบบเอง ควรตรวจเงื่อนไข ราคา และข้อจำกัดของบริการที่เลือกในช่วงเวลาที่ใช้งาน |
| Apache Kafka (แบบเต็มรูปแบบ) | ต่อยอดจาก Lab 4 — ตั้ง Kafka broker จริงแทน socket source เพื่อเรียนรู้ message queue ที่ใช้งานจริงในอุตสาหกรรม |
| Kubernetes | วิธี deploy Spark cluster บน production จริง แทนที่ docker-compose ที่ใช้ใน Lab 0 (ซึ่งเหมาะกับการเรียนรู้ ไม่ใช่ production) |
| Cloud Data Warehouse (Snowflake/BigQuery) | ทางเลือกที่ต่างจาก self-managed Spark — เหมาะเข้าใจ trade-off ระหว่าง "ดูแลเอง" กับ "จ่ายเงินให้คนอื่นดูแล" ตามที่กล่าวถึงในบทที่ 3 |
| MLOps (MLflow, Kubeflow) | ต่อยอดจาก Lab 3 — จัดการ lifecycle ของโมเดล ML ในระดับ production (versioning, monitoring, retraining) |
20วิธีทำแล็บให้ได้มากกว่าคำว่า “รันผ่าน”
แล็บนี้ไม่ได้วัดว่าเราพิมพ์คำสั่งตามตัวอย่างได้ครบหรือไม่ เพราะการรันผ่านอาจเกิดจากความบังเอิญ ค่า Default หรือข้อมูลที่เล็กเกินไปจนมองไม่เห็นปัญหา เป้าหมายคือฝึกตั้งสมมติฐาน เปลี่ยนตัวแปรครั้งละอย่าง เก็บหลักฐาน และอธิบายผลด้วยแนวคิดของระบบกระจาย ถ้าผลไม่ตรงกับที่คาด นั่นไม่ใช่ความล้มเหลว แต่เป็นจุดเริ่มต้นของคำถามที่ดี
- คาดก่อนรัน: เขียนหนึ่งหรือสองประโยคว่าคิดว่าจะเกิดอะไรและเพราะอะไร
- กำหนดสิ่งที่คุม: ใช้ข้อมูล โค้ด และทรัพยากรเดิม แล้วเปลี่ยนเฉพาะตัวแปรที่กำลังศึกษา
- เก็บหลักฐาน: บันทึกเวลา แผนการทำงาน Metric, Log หรือภาพ Spark UI ไม่อาศัยความรู้สึกว่า “เร็วขึ้น”
- อธิบายกลไก: เชื่อมผลกับ Partition, Shuffle, State, Memory, Network หรือ Scheduling
- บอกข้อจำกัด: ผลจาก Laptop และข้อมูลจำลองอาจไม่เหมือน Production ให้ระบุสิ่งที่ยังสรุปไม่ได้
21สมุดบันทึกการทดลอง
| รายการ | สิ่งที่ควรบันทึก | เหตุผล |
|---|---|---|
| คำถาม | ครั้งนี้ต้องการรู้อะไรเพียงเรื่องเดียว | กันการทดลองหลุดประเด็น |
| สมมติฐาน | ผลที่คาดและกลไกที่คิดว่าเป็นสาเหตุ | ทำให้ตรวจความเข้าใจได้ |
| ตัวแปร | สิ่งที่เปลี่ยน สิ่งที่คุม และค่าตั้งต้น | ทำให้เปรียบเทียบอย่างเป็นธรรม |
| หลักฐาน | เวลา Metric, Plan, Log, UI และ Sample output | ทำให้คนอื่นตรวจซ้ำได้ |
| ข้อสรุป | หลักฐานสนับสนุนหรือหักล้างสมมติฐานอย่างไร | แยกข้อเท็จจริงออกจากความเห็น |
| คำถามใหม่ | ถ้ามีเวลาเพิ่ม จะเปลี่ยนอะไรต่อ | เชื่อมไปสู่การทดลองรอบถัดไป |
อย่าจดเฉพาะผลลัพธ์สุดท้าย ควรจด Environment ด้วย เช่น Spark version, Python version, จำนวน Core, Memory, จำนวน Partition, Seed และขนาดข้อมูล เปรียบเหมือนใบเสร็จและสูตรอาหารที่ทำให้คนอื่นย้อนทำจานเดิมได้ หากไม่มีข้อมูลเหล่านี้ ผลที่ดูน่าเชื่อถืออาจทำซ้ำไม่ได้
22ชุดการทดลองหลัก: Capstone
การทดลอง 1: ตั้งคำถามที่ตัดสินใจได้
ลงมือทำ: เปลี่ยนหัวข้อกว้างให้เป็นคำถาม ผู้ใช้คำตอบ และการตัดสินใจที่ตามมา ก่อนรันให้เขียนผลที่คาดไว้ แล้วรันอย่างน้อยสามครั้งหากกำลังเปรียบเทียบเวลา เพื่อไม่ให้การเริ่ม JVM, Cache หรือ Background process เพียงครั้งเดียวหลอกเรา
หลักฐานที่ต้องเก็บ: Problem statement หนึ่งหน้าและ Non-goal ที่ชัดเจน แนบค่าตั้งต้นและขนาดข้อมูล เพื่อให้เพื่อนสามารถตรวจซ้ำได้
คำถามที่ต้องตอบ: ผลต่างมาจากการคำนวณ การสื่อสาร การอ่านเขียนข้อมูล หรือการรอคิว? ถ้าขยายข้อมูลสิบเท่า แนวโน้มเดิมน่าจะยังอยู่หรือไม่ เพราะอะไร?
การทดลอง 2: ทำ Baseline ก่อน
ลงมือทำ: สร้างวิธีง่ายที่สุดที่ให้คำตอบได้ก่อนเพิ่ม Spark, Streaming, ML หรือ Graph ก่อนรันให้เขียนผลที่คาดไว้ แล้วรันอย่างน้อยสามครั้งหากกำลังเปรียบเทียบเวลา เพื่อไม่ให้การเริ่ม JVM, Cache หรือ Background process เพียงครั้งเดียวหลอกเรา
หลักฐานที่ต้องเก็บ: Baseline metric, เวลา และข้อจำกัด แนบค่าตั้งต้นและขนาดข้อมูล เพื่อให้เพื่อนสามารถตรวจซ้ำได้
คำถามที่ต้องตอบ: ผลต่างมาจากการคำนวณ การสื่อสาร การอ่านเขียนข้อมูล หรือการรอคิว? ถ้าขยายข้อมูลสิบเท่า แนวโน้มเดิมน่าจะยังอยู่หรือไม่ เพราะอะไร?
การทดลอง 3: กำหนด Data Contract
ลงมือทำ: ระบุ Schema, Null, Key, Event Time, หน่วย และกฎคุณภาพ ก่อนรันให้เขียนผลที่คาดไว้ แล้วรันอย่างน้อยสามครั้งหากกำลังเปรียบเทียบเวลา เพื่อไม่ให้การเริ่ม JVM, Cache หรือ Background process เพียงครั้งเดียวหลอกเรา
หลักฐานที่ต้องเก็บ: Data dictionary กับตัวอย่าง Record ดีและ Record เสีย แนบค่าตั้งต้นและขนาดข้อมูล เพื่อให้เพื่อนสามารถตรวจซ้ำได้
คำถามที่ต้องตอบ: ผลต่างมาจากการคำนวณ การสื่อสาร การอ่านเขียนข้อมูล หรือการรอคิว? ถ้าขยายข้อมูลสิบเท่า แนวโน้มเดิมน่าจะยังอยู่หรือไม่ เพราะอะไร?
การทดลอง 4: ออกแบบ Failure Drill
ลงมือทำ: เลือกความเสียหายหนึ่งแบบ เช่นไฟล์ซ้ำ Worker หยุด หรือข้อมูลมาสาย ก่อนรันให้เขียนผลที่คาดไว้ แล้วรันอย่างน้อยสามครั้งหากกำลังเปรียบเทียบเวลา เพื่อไม่ให้การเริ่ม JVM, Cache หรือ Background process เพียงครั้งเดียวหลอกเรา
หลักฐานที่ต้องเก็บ: ขั้นตอนทดลอง หลักฐานการกู้ และผลต่อความถูกต้อง แนบค่าตั้งต้นและขนาดข้อมูล เพื่อให้เพื่อนสามารถตรวจซ้ำได้
คำถามที่ต้องตอบ: ผลต่างมาจากการคำนวณ การสื่อสาร การอ่านเขียนข้อมูล หรือการรอคิว? ถ้าขยายข้อมูลสิบเท่า แนวโน้มเดิมน่าจะยังอยู่หรือไม่ เพราะอะไร?
การทดลอง 5: ซ้อม Demo แบบมีทางหนี
ลงมือทำ: เตรียม Live demo และหลักฐานสำรองเมื่อระบบภายนอกล่ม ก่อนรันให้เขียนผลที่คาดไว้ แล้วรันอย่างน้อยสามครั้งหากกำลังเปรียบเทียบเวลา เพื่อไม่ให้การเริ่ม JVM, Cache หรือ Background process เพียงครั้งเดียวหลอกเรา
หลักฐานที่ต้องเก็บ: Demo script 7 นาที Screenshot และผลลัพธ์ที่ทำซ้ำได้ แนบค่าตั้งต้นและขนาดข้อมูล เพื่อให้เพื่อนสามารถตรวจซ้ำได้
คำถามที่ต้องตอบ: ผลต่างมาจากการคำนวณ การสื่อสาร การอ่านเขียนข้อมูล หรือการรอคิว? ถ้าขยายข้อมูลสิบเท่า แนวโน้มเดิมน่าจะยังอยู่หรือไม่ เพราะอะไร?
23บันไดแก้ปัญหาเมื่อผลไม่เป็นอย่างที่คิด
เวลางานล้ม อย่าเริ่มด้วยการลบทุกอย่างแล้วติดตั้งใหม่ เพราะเราอาจทำลายหลักฐานที่บอกสาเหตุ ให้ไล่จากชั้นนอกเข้าสู่ชั้นในเหมือนช่างไฟที่ตรวจตั้งแต่ปลั๊ก สายไฟ ฟิวส์ ไปจนถึงเครื่องใช้ไฟฟ้า
- ยืนยันอาการ: คัดลอก Error แรก ไม่ใช่เฉพาะบรรทัดสุดท้าย และบันทึกคำสั่งที่ทำให้เกิดซ้ำ
- ลดปัญหา: ใช้ข้อมูลเล็กที่สุดและโค้ดสั้นที่สุดที่ยังทำให้ Error เกิด
- ตรวจสัญญาข้อมูล: ดู Schema, Type, Null, Key และ Path ก่อนสงสัย Cluster
- ตรวจ Plan และ UI: ดูว่างานเริ่มจริงหรือค้างอยู่ก่อนสร้าง Job; แยกปัญหา Driver, Executor และ Storage
- ตรวจทรัพยากร: ดู Memory, Disk, Port, Permission และ Container status
- เปลี่ยนทีละจุด: เมื่อแก้แล้ว ให้ย้อนอธิบายว่าการเปลี่ยนนั้นจัดการสาเหตุใด
24คำถามชวนคิดหลังทำแล็บ
- ผลที่เห็นเกิดจาก Algorithm หรือเกิดจากการจัดวางข้อมูลและข้อจำกัดของเครื่อง?
- ถ้าข้อมูลใหญ่ขึ้นหนึ่งร้อยเท่า ขั้นตอนไหนจะพังก่อน และเรามีหลักฐานอะไร?
- ถ้าเครื่องหนึ่งหายไประหว่างงาน คำตอบจะยังถูกต้องหรือเพียงแค่งานยังรันต่อได้?
- ค่า Default ใดช่วยเราอยู่ และค่าใดอาจกลายเป็นกับดักเมื่อขึ้น Production?
- ถ้าต้องอธิบายผลให้เพื่อนที่ไม่ได้เห็นหน้าจอ เรามีหลักฐานครบพอหรือยัง?
25สิ่งที่ต้องส่ง
- Notebook หรือ Source code ที่รันจากต้นจนจบได้ โดยไม่พึ่งลำดับคำสั่งที่ซ่อนอยู่
- README ระบุวิธีเริ่มระบบ Version, Dependency และคำสั่งที่ใช้
- สมุดบันทึกอย่างน้อยสามการทดลอง มีสมมติฐาน ตัวแปร หลักฐาน และข้อสรุป
- ภาพหรือ Export จาก Spark UI/Query Plan ที่วงส่วนสำคัญและมีคำอธิบาย
- กรณีผิดพลาดอย่างน้อยหนึ่งกรณี พร้อมการวิเคราะห์ ไม่ตัดทิ้งเพราะ “ทำไม่สำเร็จ”
- ข้อจำกัดของผลและสิ่งที่จะทดลองต่อ หากมีข้อมูลหรือเครื่องมากขึ้น
26เกณฑ์ตรวจงานแบบสั้น
| ด้าน | งานที่ผ่าน | งานที่เข้าใจจริง |
|---|---|---|
| ความถูกต้อง | รันได้และได้คำตอบ | ตรวจ Schema, Edge case และเทียบกับคำตอบเล็กที่คำนวณเองได้ |
| การทดลอง | มีผลหนึ่งชุด | คุมตัวแปร ทำซ้ำ และอธิบายความแปรปรวน |
| หลักฐาน | มี Screenshot | เลือก Metric หรือ Plan ที่ตอบคำถามและตีความถูก |
| ความเข้าใจ | บอกว่าอะไรเร็วกว่า | อธิบายกลไกและเงื่อนไขที่ข้อสรุปอาจกลับด้าน |
| การสื่อสาร | มี Code | ผู้อื่นทำซ้ำได้และเห็นเส้นทางจากคำถามไปถึงข้อสรุป |
27สรุปและขั้นตอนถัดไป
หัวใจของแล็บนี้ไม่ใช่จำคำสั่ง แต่คือการมองเห็นว่า Capstone ตัดสินใจอย่างไรเมื่อข้อมูล งาน และทรัพยากรถูกกระจายออกจากกัน เมื่อทำเสร็จแล้วควรตอบได้สามเรื่อง: ระบบทำอะไร หลักฐานใดแสดงว่ามันทำเช่นนั้น และเงื่อนไขใดทำให้พฤติกรรมเปลี่ยน
ก่อนเปิดแล็บถัดไป ลองย่อสิ่งที่เรียนรู้ให้เหลือหนึ่งภาพ หนึ่งตาราง และสามประโยค หากย่อไม่ได้ อาจยังมีส่วนที่เราเห็นผลแต่ยังไม่เข้าใจกลไก ให้กลับไปเลือกการทดลองที่เล็กลง แล้วค่อยต่อภาพกลับขึ้นมาใหม่
28สถานการณ์จำลอง: จากข้อมูลก้อนเล็กไปสู่งานที่เริ่มมีปัญหา
ให้เริ่มด้วยข้อมูลก้อนเล็กที่ตรวจคำตอบด้วยมือได้ จากนั้นขยายเป็นสามระดับ โดยไม่เปลี่ยนความหมายของโจทย์ ระดับแรกใช้ตรวจความถูกต้อง ระดับที่สองใช้เปิดให้เห็น Parallelism และระดับที่สามใช้เปิดให้เห็นคอขวด วิธีนี้ช่วยแยกคำถามสองข้อที่มักปนกัน คือ “คำตอบถูกหรือไม่” กับ “ระบบรองรับขนาดงานได้หรือไม่” ระบบที่เร็วแต่ตอบผิดไม่มีประโยชน์ และระบบที่ตอบถูกเฉพาะข้อมูลสิบแถวก็ยังไม่ใช่คำตอบของงานขนาดใหญ่
| ระดับ | จุดประสงค์ | สิ่งที่ควรเห็น | สิ่งที่ยังสรุปไม่ได้ |
|---|---|---|---|
| เล็กมาก | ตรวจคำตอบด้วยมือและทดสอบ Edge case | Output ทุกแถวและลำดับการแปลงข้อมูล | ประสิทธิภาพและการกระจายงาน |
| พอดีเครื่อง | ดูจำนวน Task, Partition และการใช้ Core | งานหลาย Task ทำพร้อมกันและมี Metric ให้อ่าน | พฤติกรรมเมื่อ Memory ไม่พอ |
| เริ่มเกินหน่วยความจำ | ดู Spill, Shuffle, GC และการอ่านเขียน Disk | คอขวดปรากฏชัดใน UI | พฤติกรรมของคลัสเตอร์ Production ขนาดใหญ่ |
| ข้อมูลเอียง | ดูผลของ Key หรือกลุ่มที่ใหญ่ผิดปกติ | Task บางตัวช้ากว่าเพื่อนอย่างชัดเจน | ว่าวิธีแก้หนึ่งแบบเหมาะกับข้อมูลทุกชุด |
29อ่าน Spark UI ให้เป็นเรื่องราว ไม่ใช่เพียงหน้าจอสีสวย
เริ่มจาก Job ว่าถูกสร้างเพราะ Action ใด แล้วลงไปที่ Stage เพื่อดูว่า Shuffle แบ่งเส้นทางตรงไหน จากนั้นจึงดู Task ว่ากระจายตัวสม่ำเสมอหรือมีตัวใดลากยาว สุดท้ายดู Executor ว่างานไปอยู่เครื่องใด ใช้ Memory เท่าไร และมี Failure หรือ Retry หรือไม่ ลำดับนี้เหมือนอ่านแผนที่จากประเทศ จังหวัด ถนน แล้วจึงถึงบ้าน หากกระโดดไปดู Task หนึ่งตัวทันที เราอาจเห็นอาการแต่ไม่เห็นบริบท
| หน้าหรือ Metric | คำถามที่ตอบได้ | สัญญาณที่ควรสงสัย |
|---|---|---|
| Jobs | Action ใดเริ่มการคำนวณ และจบหรือยัง | มี Job มากกว่าที่คาดจากการเรียก Action ซ้ำ |
| Stages | งานถูกตัดตรงไหนและ Stage ใดใช้เวลามาก | Stage หลัง Shuffle ใช้เวลาครองงานทั้งหมด |
| Tasks | งานย่อยกระจายสม่ำเสมอหรือไม่ | Max สูงกว่า Median มาก บ่งชี้ Skew หรือเครื่องช้า |
| Executors | ใช้ Core/Memory/Storage อย่างไร | Executor หาย, Task Failed, GC สูง หรือ Disk Spill มาก |
| SQL Plan | Optimizer เลือก Scan, Join และ Exchange แบบใด | อ่านคอลัมน์เกินจำเป็น มี Exchange ซ้ำ หรือ Join ผิดคาด |
| Storage | Cache อะไร อยู่ระดับใด และกินพื้นที่เท่าไร | Cache ไว้แต่ไม่ถูกใช้ หรือผลักข้อมูลสำคัญออกจาก Memory |
การจับภาพ UI ควรใส่ลูกศรหรือคำอธิบายว่ากำลังใช้ภาพนั้นสนับสนุนข้อสรุปใด ภาพทั้งหน้าที่ไม่มีคำอธิบายเหมือนแนบผลตรวจสุขภาพโดยไม่บอกว่าค่าไหนผิดปกติ หลักฐานที่ดีไม่จำเป็นต้องเยอะ แต่ต้องเชื่อมกับคำถามได้ตรงจุด
30แยกความถูกต้อง ความเร็ว และความทนทานออกจากกัน
สามเรื่องนี้สัมพันธ์กันแต่ทดแทนกันไม่ได้ งานอาจเร็วขึ้นเพราะเผลอทิ้งข้อมูลบางส่วน งานอาจทนต่อ Worker หายแต่สร้างข้อมูลซ้ำ หรือคำตอบอาจถูกแต่ใช้ทรัพยากรมากเกินจำเป็น ทุกครั้งที่ปรับระบบจึงควรตรวจทั้งสามแกน ไม่ประกาศชัยชนะจากเวลาเพียงตัวเดียว
- ความถูกต้อง: สร้างข้อมูลจิ๋วที่รู้คำตอบล่วงหน้า ใส่ Null, Duplicate, Key ที่ไม่มีคู่ และค่าขอบเขต แล้วตรวจผลทีละกรณี
- ความเร็ว: วัดหลายรอบ แยก Warm-up ออกจากรอบจริง ระบุขนาดข้อมูลและทรัพยากร และรายงานทั้งค่ากลางกับช่วง ไม่เลือกเฉพาะรอบที่ดีที่สุด
- ความทนทาน: ทำให้ส่วนหนึ่งล้มอย่างตั้งใจ ตรวจว่างาน Retry, Resume หรือคำนวณใหม่จาก Lineage และตรวจว่าคำตอบหลังการกู้ไม่ซ้ำหรือขาด
- ต้นทุน: เวลาเร็วขึ้นอาจแลกกับ Memory, Storage, Network หรือความซับซ้อนในการดูแล ให้บันทึกสิ่งที่จ่ายเพิ่มเสมอ
31จาก Error Message ไปสู่คำอธิบาย
ให้เลือก Error จริงหนึ่งครั้งจากแล็บแล้วเขียน Postmortem สั้น ๆ โดยไม่กล่าวโทษผู้ใช้หรือเครื่องมือ เริ่มจากผลกระทบ ตามด้วยลำดับเหตุการณ์ สาเหตุใกล้ตัว สาเหตุราก วิธีแก้เฉพาะหน้า และวิธีป้องกันซ้ำ ตัวอย่างเช่น “Job ล้มเพราะ Out of Memory” ยังเป็นเพียงอาการ สาเหตุรากอาจเป็นการ collect ข้อมูลทั้งหมดมายัง Driver, Broadcast ตารางใหญ่เกินไป หรือ Partition หนึ่งก้อนใหญ่ผิดปกติ ซึ่งมีวิธีแก้คนละแบบ
| ส่วนของ Postmortem | ตัวอย่างคำถาม |
|---|---|
| ผลกระทบ | งานใดหยุด คำตอบใดขาด และเสียเวลาเท่าไร |
| ลำดับเหตุการณ์ | คำสั่งใดเกิดก่อน Error; Metric เริ่มผิดปกติเมื่อใด |
| สาเหตุราก | การตัดสินใจหรือข้อสมมติใดทำให้ปัญหาเกิดได้ |
| การกู้ | ทำอย่างไรให้งานกลับมา และข้อมูลถูกตรวจซ้ำอย่างไร |
| การป้องกัน | เพิ่ม Test, Validation, Alert หรือเปลี่ยน Design ตรงไหน |
จุดสำคัญคือแยก “แก้ให้งานผ่านครั้งนี้” ออกจาก “แก้ไม่ให้เกิดซ้ำ” การเพิ่ม Memory อาจช่วยงานรอบนี้ แต่ถ้าข้อมูลโตต่อเนื่อง ปัญหาจะกลับมา การเปลี่ยนรูปแบบ Aggregation, ลดข้อมูลก่อน Shuffle หรือเลิกดึงทุกอย่างเข้า Driver อาจแตะสาเหตุได้ตรงกว่า
32แบบฝึกสอนกลับ: อธิบายให้เพื่อนฟังในห้านาที
จับคู่กับเพื่อนแล้วผลัดกันอธิบาย Capstone โดยห้ามเริ่มจากชื่อ Class หรือ API ให้เริ่มจากปัญหาที่ระบบกำลังแก้ ใช้ภาพหนึ่งภาพและตัวอย่างข้อมูลไม่เกินสิบแถว ผู้ฟังมีหน้าที่ถามว่า “รู้ได้อย่างไร” และ “ถ้าข้อมูลใหญ่ขึ้นจะเกิดอะไร” วิธีนี้ช่วยเปิดจุดที่เราจำคำสั่งได้แต่ยังเชื่อมเหตุผลไม่ครบ
- นาทีที่ 1: ปัญหาคืออะไร และเหตุใดเครื่องเดียวหรือวิธีตรงไปตรงมาจึงเริ่มไม่พอ
- นาทีที่ 2: ข้อมูลและงานถูกแบ่งอย่างไร ส่วนใดอยู่ที่ Driver และส่วนใดอยู่ที่ Executor
- นาทีที่ 3: จุดใดต้องสื่อสารข้ามเครื่อง และต้นทุนเกิดตรงไหน
- นาทีที่ 4: แสดงหลักฐานหนึ่งชิ้นจากแล็บแล้วตีความ
- นาทีที่ 5: บอกข้อจำกัดหนึ่งข้อและการทดลองถัดไปหนึ่งอย่าง