ใน course Microservices ที่ Skooldio นั้น
มีคำถามเรื่องเกี่ยวกับรูปแบบของการแลกเปลี่ยนข้อมูลระหว่าง service
ว่า CDC (Change Data Capture) และ Outbox pattern มันเป็นอย่างไร
จึงทำการอธิบายพร้อมตัวอย่าง code และเครื่องมือ
ที่ผมมีโอกาสใช้งานในงานมาบ้าง
เลยทำการสรุปและบันทึกแนวทางไว้นิดหน่อย

ในการแลกเปลี่ยนข้อมูลระหว่าง service นั้นมีหลายรูปแบบ เช่น

  • การเรียกหรือส่งข้อมูลแบบตรง ๆ จาก service ไปเลย บ่อยครั้งมีรูปแบบเป็น synchronous ต้องระวังเรื่องของ cascade failure ไว้ด้วย
  • เป็น Event-based ในรูปแบบของ one-to-one หรือ one-to-many ก็ว่าไป มีรูปแบบเป็น asynchronous ต้องสร้าง code ทั้งสองฝั่งขึ้นมา เพื่อส่งและรับข้อมูล เช่น producer/consumer หรือ publisher/subscriber เป็นต้น
  • Share database กันไปเลย หรือ replicate database ออกมา !! แต่ต้องการข้อมูลทั้งหมดนั้นจริง ๆ ไป

หรือทำการ replicate data แต่แบบเลือกได้
นั่นคือ เมื่อเกิดการเปลี่ยนแปลงใน data ที่เราสนใจใน database (Event/Change logs)
จะทำการจับการเปลี่ยนแปลง ทำการ transform ข้อมูลให้อยู๋ในรูปแบบที่ต้องการ
จากนั้นก็ทำการส่ง หรือ บันทึกไว้อีกที่ที่ต้องการใช้งาน
โดยไม่ต้องไปทำในฝั่งของ app/service
และทำงานร่วมกับ Event-based ก็เป็นอีกทางเลือกหนึ่ง
ซึ่งจะเรียกวิธีการนี้ว่า Change Data Capture (CDC)

โดยเครื่องมือที่ใช้งานเช่น Debezium

มีโครงสร้างการทำงานดังรูป

การทำงานนั้น Debezium จะทำการอ่าน event หรือการเปลี่ยนแปลงใน database แต่ละชนิด
เช่น

  • MySQL จะทำการอ่านจาก binlog
  • Postgresql จะทำการอ่าจาก logical replication stream

ซึ่งจะมี connector ไปยัง database อื่น ๆ ให้อีกเพียบ
จากนั้นเราสามารถ custom สิ่งที่ต้องการได้อีกด้วย
ด้วยการเขียนตัว transformer data ได้อีก หรือดักบาง event หรือบาง table ก็ได้

ยกตัวอย่างการเขียน transformer เพื่อจัดการกับ event การสร้างเท่านั้น จาก Pogresql database

จากนั้นก็อยู่ที่ว่าจะทำการ config เพื่อให้ข้อมูลที่เราดักจับนั้นไปไว้ที่ไหน
โดย Debezium นั้นสามารถส่งข้อมูลไปยัง messaging ได้ เช่น Apahe Kafka
เพื่อให้ใครก็ได้มา subscribe เพื่อนำข้อมูลต่าง ๆ เหล่านี้ไปใช้งานต่อไป
แสดงดังรูป

แต่ก็บ่อยครั้งข้อมูลหรือการเปลี่ยนแปลงใน database จะเยอะมาก ๆ
รวมทั้งไม่มั่นใจอีกว่าการเปลี่ยนแปลงเหล่านั้น
จะถูกดักจับ และ ส่งมายัง messaging ได้ครบหรือไม่
ดังนั้นจึงจำเป็นต้องกาวิธีการจัดการ หนึ่งในแนวคิดคือ Outbox pattern

แนวคิดง่าย ๆ คือ เมื่อมีการเปลี่ยนแปลงของ database เกิดขึ้น
ใน app/service จะทำการเขียน code เพื่อบันทึกลง table หนึ่ง ๆ ไว้
จากนั้นเมื่อทำการส่งข้อมูลไปยัง messaging เรียบร้อยแล้ว
ก็จะทำการ update หรือลบข้อมูลนั้น ๆ ใน table ไป
โดย table นี้เราจะเรียกว่า outbox table

ดังนั้นถ้าเรากำหนดไว้ว่า เมื่อส่งข้อมูลเสร็จแล้ว ข้อมูลต้องโดนลบออกไปเสมอ
ถ้าทำงานได้อย่างถูกต้องใน outbox table ต้องไม่มีข้อมูลเหลือ

แสดงการทำงานดังรูป

จากนั้นเราก็ทำการ config ใน Debezium ว่า
ให้สนใจเฉพาะการเปลี่ยนแปลงใน outbox table ก็พอ
ทำให้ง่าย และ สะดวกต่อการใช้งานอีกด้วย

ตัวอย่างของการ config แบบง่าย ๆ

เพียงเท่านี้ก็สามารถใช้งาน Debezium + Apache Kafka
สำหรับการแลกเปลี่ยนข้อมูลระหว่างระบบ หรือ service ได้แล้ว !!

สุดท้ายแล้ว วิธีการเหล่านี้มีความซับซ้อนสูงมาก ๆ

แต่ก็มีประโยชน์มากเช่นกัน
ดังนั้นก่อนใช้งานควรต้องรู้และเข้าใจ
ว่าทำไมเราต้องใช้งาน
มีวิธีการอื่น ๆ ไหม
ที่เหมาสมต่อปัญหา และ ทีม
รวมทั้งเรื่องของการ monitoring และ troubleshooting ต่าง ๆ ด้วย
ทุกอย่างล้วนมี tradeoff ทั้งสิ้น
ใช้อย่างมีสติ
นำมาแก้ไขปัญหา ไม่ใช่นำมาใช้เพื่อสร้างปัญหา

Reference Websites