3 คะแนน โดย GN⁺ 2025-02-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ภูมิหลังของการนำ Flink SQL มาใช้

  • ในบรรดาแอปที่พัฒนาบน Flink ซึ่ง Azar Matching Dev Team ดูแลอยู่ มีแอป legacy ขนาดใหญ่ที่ใช้ CPU 96 คอร์
  • แอปนี้นำหลายฟีเจอร์มารวมไว้ในโครงสร้างแบบโมโนลิทิก ทำให้ดูแลรักษายาก
  • เมื่อมีการเปลี่ยนโหนดที่รันแอปจากงานด้านอินฟราสตรักเจอร์ ก็เกิดปัญหาที่ทำให้แอปทำงานไม่ปกติ
  • จึงต้องตัดสินใจว่าจะยอมรับภาระในการดูแลระบบที่สูงต่อไป หรือจะหาวิธีอื่นมาแทน

ตัวเลือกที่สามารถเลือกได้

  • ฟังก์ชันสำคัญของแอปเดิมนั้นถูกพัฒนาไว้ในแอป Flink ใหม่แล้ว
  • จึงพิจารณาวิธีทดแทนส่วนที่ทำหน้าที่เผยแพร่ event แบบมีเงื่อนไขและประมวลผล logic
    1. พัฒนาเป็น Flink App เดียว
      • ข้อดี: ดูแลง่าย
      • ข้อเสีย: แอปมีแนวโน้มจะใหญ่ขึ้นมาก และหากส่วนหนึ่งล้มเหลวก็มีโอกาสกระทบฟังก์ชันอื่นได้ง่าย
    2. พัฒนาเป็นหลาย Flink App
      • ข้อดี: จัดการแยกจากกันได้อย่างอิสระ
      • ข้อเสีย: เมื่อจำนวนแอปเพิ่มขึ้น ภาระก็มากขึ้น
    3. ใช้ Flink SQL
      • ข้อดี: กำหนด logic ได้ด้วยคิวรี และดูแลเพียงคลัสเตอร์เดียว
      • ข้อเสีย: แสดง logic ที่ซับซ้อนได้ยาก และถ้าไม่คุ้นกับการดูแลคลัสเตอร์ก็อาจใช้งานยาก

เหตุผลที่เลือก Flink SQL และการเปรียบเทียบกับเทคโนโลยีทางเลือก

  • ก่อนนำ Flink SQL มาใช้ ได้พิจารณา ksqlDB และ Spark Structured Streaming ก่อน
  • เหตุผลที่เลือก Flink SQL:
    1. High Availability
      • สามารถบันทึกและกู้คืนสถานะแอปได้อย่างเสถียรผ่าน Checkpoint และ Savepoint
      • สามารถตั้งค่า JobManager ให้ทำงานในโหมด HA ได้
    2. รองรับฟีเจอร์สตรีมมิงขั้นสูง
      • รองรับความสามารถด้านการประมวลผลสตรีมมิงที่หลากหลายผ่านไวยากรณ์ SQL
      • รองรับ window, join, event time processing, watermark เป็นต้น
    3. ขยายความสามารถได้ผ่าน UDF และ Custom Connector
      • สามารถเชื่อมต่อกับฟังก์ชันที่ผู้ใช้กำหนดเองและแหล่งข้อมูลหรือ sink ที่หลากหลายได้

เทียบกับ ksqlDB

  • แม้จะรวมอยู่ในแพลตฟอร์ม Confluent แต่การทำงานแบบ HA ในการประมวลผลสตรีมมิงแบบ stateful ยังไม่มีประสิทธิภาพนัก

เทียบกับ Spark Structured Streaming

  • พัฒนาบน Spark SQL engine และสามารถเขียน UDF กับ Custom Sink ได้
  • แต่ทำงานแบบ micro-batch จึงอาจเสียเปรียบในงานประมวลผลแบบเรียลไทม์

การสร้างสภาพแวดล้อมคลัสเตอร์และวิธี deploy คิวรี

ทดสอบแบบง่าย ๆ บนเครื่องโลคัล

  • แนะนำวิธีรัน Flink Cluster บนเครื่องโลคัลและส่ง SQL คิวรีเข้าไป

สถาปัตยกรรมคลัสเตอร์ในสภาพแวดล้อม production

  • สร้าง Flink SQL Cluster บน Kubernetes
  • เปรียบเทียบระหว่าง Application mode และ Session mode

deploy คิวรีด้วยแนวทาง GitOps

  • ใช้ GitHub Actions สำหรับ deploy คิวรีและสั่งหยุด Job

กรณี operation หลักและประสบการณ์ troubleshooting

กรณีที่ JobManager หรือ TaskManager ล้มเหลว

  • JobManager สามารถทำงานต่อได้แม้เกิดความล้มเหลว หากตั้งค่า HA ไว้
  • ส่วน TaskManager เมื่อเกิดความล้มเหลว งานจะถูกกระจายใหม่และทำงานต่อได้

กรณีที่คิวรีล้มเหลว

  • อาจเกิดจากข้อมูลผิดปกติที่ไหลเข้ามาหรือทรัพยากรคอมพิวต์ไม่เพียงพอ
  • สามารถตั้งค่าให้ข้าม error ของฟอร์แมต JSON และกำหนดค่าเริ่มต้นได้

กรณีที่บาง Job ล้มเหลวเมื่อรีสตาร์ตคลัสเตอร์

  • จำเป็นต้องปรับการตั้งค่า timeout และ retry

กรณีที่ต้องการแก้เงื่อนไขของคิวรีเพียงจุดเดียวแล้ว deploy ใหม่

  • หากเป็นการแก้ไขเล็กน้อยเท่านั้น ก็สามารถใช้ savepoint เพื่อกู้คืน state ได้

จุดสำคัญที่ควรมอนิเตอร์

  • ตรวจสอบเมตริก เช่น numRunningJobs, taskmanager.cpu.load, taskmanager.memory.used

ทิ้งท้าย

  • การนำ Flink SQL มาใช้ช่วยเพิ่มทั้งประสิทธิภาพการทำงานและประสิทธิภาพในการดูแลระบบ
  • มีความเสถียรสูง และมีแผนจะนำรูปแบบ GitOps Controller มาใช้งาน

1 ความคิดเห็น

 
flgkselql98 2025-02-26

ระบบแบบกระจายอย่าง flink จำเป็นต้องคงไว้ซึ่ง HA ด้วยการมี rack 2~3 ชุด และดูเหมือนว่าพอผนวกกับ kubernetes แล้วก็เหมือนจะรับประกัน HA ได้ แต่สุดท้ายก็คงต้องคิดเรื่องทรัพยากรของ kube slave node อยู่ดี เลยสงสัยว่าเขาจัด node ที่รันแต่ flink แยกไว้หรือเปล่า (ถ้า flink มีโหลดสูง ก็น่าจะมีปัญหา slave node ล่มได้)
ในมุมแบบนั้น การใช้ kubernetes มีข้อดีอะไรบ้างไหม?

อีกอย่าง ถ้าใช้ window function ใน flink ข้อมูลระหว่างนั้นจะถูกเก็บไว้ในหน่วยความจำ ทำให้คำสั่ง SQL join ทำงานได้ แต่ถ้ามองในแง่ trade-off ก็เลยทำให้คิดว่า flink เป็นตัวเลือกที่ดีจริงหรือเปล่า ถ้าเวลาผ่านไปแล้ว SQL + job ขนาดใหญ่ขึ้นเรื่อยๆ แล้ว job ตายขึ้นมา ผลกระทบก็คงมหาศาล..

ผมเองก็สงสัยเหมือนกันว่า ถ้าอยู่ในสถานการณ์ที่ต้อง join กันตั้งแต่ data source ชั้นบนสุด จะมีวิธีไหนที่ไม่ใช้ flink แล้วลดระดับมาจัดการที่ application level ได้บ้าง.