แยกอ่าน-เขียนด้วย Read Replica เทคนิคทำเว็บลื่นเมื่อทราฟฟิกพุ่ง
Read Replica คือวิธีแยกภาระงานอ่านออกจากฐานข้อมูลหลัก เพื่อลดความหน่วงและช่วยให้ระบบรองรับทราฟฟิกสูงได้ดีขึ้น แต่การใช้งานให้ได้ผลต้องออกแบบเส้นทางอ่านเขียนและระวังเรื่องข้อมูลหน่วงเวลาให้เหมาะสม.

แยกอ่าน-เขียนด้วย Read Replica เทคนิคทำเว็บลื่นเมื่อทราฟฟิกพุ่ง
หลายครั้งที่เว็บไซต์เริ่มช้าลงในช่วงทราฟฟิกสูง สาเหตุไม่ได้มาจากโค้ดเพียงอย่างเดียว แต่เกิดจากฐานข้อมูลต้องรับภาระงานอ่านจำนวนมากเกินไป โดยเฉพาะในช่วงโปรโมชันหรือแคมเปญที่มีผู้ใช้งานจำนวนมากเข้ามาดูหน้าสินค้า รีวิว บทความ หรือฟีดหน้าแรก ซึ่งคำสั่งเหล่านี้ส่วนใหญ่เป็นการอ่านข้อมูลแบบ SELECT
ปัญหาคือฐานข้อมูลหลักหรือ Primary Database มักต้องรับทั้งงานเขียนและงานอ่านพร้อมกัน เมื่อจำนวนคำสั่งอ่านเพิ่มขึ้นมาก งานเขียนอย่าง INSERT, UPDATE, และ DELETE ก็อาจเริ่มรอคิว ส่งผลให้ระบบโดยรวมหน่วงและดูเหมือนสะดุด
Read Replica คืออะไร
Read Replica คือแนวคิดการแยกภาระงานอ่านออกจากฐานข้อมูลหลัก ไปให้ฐานข้อมูลอีกชุดหนึ่งช่วยรับผิดชอบแทน โดยมีรูปแบบการทำงานที่เข้าใจได้ง่ายดังนี้
- Primary รับงานเขียนเป็นหลัก
- Replica รับงานอ่านเป็นหลัก
ภาพรวมแบบง่ายคือ
- Primary:
INSERT,UPDATE,DELETE - Replica:
SELECT
ด้วยวิธีนี้ ฐานข้อมูลหลักจะมีทรัพยากรมากพอสำหรับงานสำคัญที่ต้องเขียนข้อมูล ขณะที่คำสั่งอ่านจำนวนมากจะถูกกระจายไปยัง Replica ช่วยให้เว็บไซต์ตอบสนองได้ลื่นไหลขึ้น
ทำไมหลายทีมยังไม่เริ่มใช้
แม้แนวคิดนี้จะมีประโยชน์มาก แต่หลายทีม โดยเฉพาะมือใหม่ มักยังไม่หยิบมาใช้ด้วยเหตุผลหลัก ๆ ได้แก่
- คิดว่าต้องเป็นเว็บไซต์ขนาดใหญ่มากก่อนถึงจำเป็น
- กังวลว่าการตั้งค่าจะซับซ้อน
- ยังไม่เข้าใจข้อจำกัดสำคัญเรื่องข้อมูลหน่วงเวลา
ในความเป็นจริง เว็บไซต์ขนาดกลางที่มีทราฟฟิกพุ่งเป็นช่วง ๆ ก็เริ่มได้ประโยชน์จาก Read Replica แล้ว โดยเฉพาะถ้าฐานข้อมูลเริ่มเป็นคอขวดของระบบ
ข้อจำกัดสำคัญ: ข้อมูลไม่ได้ใหม่ทันที 100%
เรื่องที่ต้องเข้าใจให้ชัดก่อนใช้งานคือ Replica ไม่ได้อัปเดตข้อมูลพร้อมกับ Primary แบบทันทีเสมอไป ข้อมูลจะถูกส่งต่อจาก Primary ไปยัง Replica ผ่านกระบวนการ replication ซึ่งอาจเกิดช่วงเวลาหน่วงสั้น ๆ หรือที่เรียกว่า replication lag
ตัวอย่างปัญหาที่เกิดขึ้นได้จริงคือ ผู้ใช้เพิ่งกดสั่งซื้อสำเร็จ ข้อมูลถูกบันทึกลง Primary แล้ว แต่เมื่อรีเฟรชหน้าทันที หากระบบพาไปอ่านจาก Replica อาจยังไม่เห็นรายการสั่งซื้อใหม่ เพราะ Replica ยังตามข้อมูลไม่ทัน
ดังนั้น การแยกอ่าน-เขียนที่ดีจึงไม่ใช่แค่เพิ่ม Replica แล้วจบ แต่ต้องกำหนดกติกาให้ชัดว่าเมื่อไรควรอ่านจาก Primary และเมื่อไรควรอ่านจาก Replica
กติกาการเลือกฐานข้อมูลที่ใช้ได้กับเว็บส่วนใหญ่
แนวทางที่นำไปปรับใช้ได้จริงมีดังนี้
1) หลังธุรกรรมสำคัญ ให้อ่านจาก Primary ชั่วคราว
กรณีที่ผู้ใช้เพิ่งทำกิจกรรมสำคัญและคาดหวังว่าจะเห็นข้อมูลล่าสุดทันที ควรบังคับให้อ่านจาก Primary เช่น
- หลังล็อกอิน
- หลังสั่งซื้อสินค้า
- หลังเปลี่ยนรหัสผ่าน
วิธีนี้ช่วยลดโอกาสที่ผู้ใช้จะเห็นข้อมูลเก่าและสับสนกับสถานะของระบบ
2) หน้าสาธารณะให้เน้น Replica และ Cache
หน้าที่มีผู้เข้าชมเยอะและไม่จำเป็นต้องแสดงข้อมูลใหม่ล่าสุดทุกวินาที เหมาะกับการอ่านจาก Replica ร่วมกับการใช้แคช เช่น
- หน้ารายการสินค้า
- บทความ
- หน้าโปรไฟล์ที่ไม่ต้องสดมาก
ถ้าทำงานร่วมกับ Redis หรือ CDN จะช่วยลดโหลดฐานข้อมูลได้อย่างชัดเจน โดยเฉพาะในช่วงทราฟฟิกกระชาก
3) งานหลังบ้านที่ต้องแม่นยำสูงให้อ่านจาก Primary
ข้อมูลบางประเภทไม่ควรยอมให้คลาดเคลื่อนแม้เพียงเล็กน้อย เช่น
- จำนวนสต็อก
- ยอดเงิน
- สถานะคำสั่งซื้อ
ข้อมูลเหล่านี้ควรอ่านจาก Primary เพื่อให้ได้ข้อมูลล่าสุดและลดความเสี่ยงทางธุรกิจ
ออกแบบโค้ดให้ใช้งานง่ายด้วย DB Router
อีกเทคนิคที่ช่วยให้การจัดการอ่าน-เขียนเป็นระบบมากขึ้น คือการทำ DB Router ในแอปพลิเคชัน เพื่อให้ทุกส่วนของโค้ดเรียกใช้ฐานข้อมูลผ่านจุดเดียว
แนวคิดตัวอย่าง เช่น
writeDB = primary
readDB = replica
คำสั่งเขียน
db.write("UPDATE products SET stock = stock-1 WHERE id=?")
คำสั่งอ่านทั่วไป
db.read("SELECT * FROM products WHERE id=?")
และเพิ่มโหมดอ่านแบบเน้นความชัวร์จาก Primary
db.readStrong("SELECT * FROM orders WHERE user_id=?")
ข้อดีของแนวทางนี้คือ ทีมพัฒนาจะควบคุมเส้นทางการอ่านเขียนได้ง่าย ไม่ต้องกระจายเงื่อนไขไว้หลายจุดในระบบ
เทคนิค Read-Your-Writes ที่ช่วยประสบการณ์ผู้ใช้
เทคนิคที่ทีมมืออาชีพนิยมใช้คือ Read-Your-Writes หมายถึงหลังจากผู้ใช้เพิ่งเขียนข้อมูล ระบบจะตั้ง session หรือ flag ชั่วคราวประมาณ 10-30 วินาที เพื่อบังคับให้คำสั่งอ่านของผู้ใช้คนนั้นวิ่งไปที่ Primary
ประโยชน์คือผู้ใช้จะมองเห็นข้อมูลที่ตัวเองเพิ่งแก้ไขหรือสร้างขึ้นทันที ลดความรู้สึกว่าระบบผิดพลาด ทั้งที่จริงเป็นเพียงผลจาก replication lag
สัดส่วนการใช้งานที่หลายทีมเริ่มต้น
ค่าตั้งต้นที่พบได้บ่อยคือ
- อ่านจาก Replica: 80-95%
- อ่านแบบ Strong จาก Primary: 5-20%
- เขียนไป Primary: 100%
สัดส่วนนี้ไม่ใช่กฎตายตัว แต่เป็นจุดเริ่มต้นที่ดีสำหรับระบบทั่วไป และสามารถปรับตามลักษณะข้อมูลและพฤติกรรมผู้ใช้ของแต่ละธุรกิจ
ใช้บริการอะไรได้บ้าง
ปัจจุบันบริการคลาวด์ช่วยให้การทำ Read Replica ง่ายขึ้นมาก ตัวเลือกที่นิยม เช่น
- AWS RDS Read Replica / Aurora Reader
- GCP Cloud SQL Read Replica
- Azure Database Replicas
- MySQL/PostgreSQL Replication สำหรับระบบที่ดูแลเอง
หากองค์กรใช้งานคลาวด์อยู่แล้ว มักเริ่มต้นได้เร็วโดยไม่ต้องดูแลโครงสร้าง replication เองทั้งหมด
สิ่งที่ต้องเตรียมก่อนเปิดใช้งานจริง
ก่อนนำ Read Replica ไปใช้ในระบบจริง ควรเตรียมความพร้อมดังนี้
- ตรวจสอบ query ที่อ่านหนักที่สุดหรือ slow queries
- เพิ่ม index ให้เหมาะสม เพราะถ้า query ไม่มีประสิทธิภาพ Replica ก็ยังช้าอยู่ดี
- วางแผน connection pool แยกฝั่ง read และ write
- ติดตั้ง monitoring สำหรับดู replication lag, read latency และ error rate
การเตรียมส่วนนี้สำคัญมาก เพราะ Read Replica ไม่ได้แก้ทุกปัญหาอัตโนมัติ หาก query เดิมช้าเพราะออกแบบไม่ดี การเพิ่ม Replica ก็อาจแค่กระจายความช้าออกไปเท่านั้น
สัญญาณว่าระบบของคุณควรเริ่มใช้ Read Replica
หากพบอาการต่อไปนี้ แปลว่าถึงเวลาพิจารณาแล้ว
- CPU หรือ IO ของฐานข้อมูลสูงมากในช่วงทราฟฟิกพุ่ง
- แอปเซิร์ฟเวอร์ยังรับโหลดได้ แต่ฐานข้อมูลเริ่มเป็นคอขวด
- หน้าเว็บอ่านข้อมูลช้ากว่าปกติในช่วงคนเข้าเยอะ
- เริ่มเกิด timeout หรือการตอบสนองช้าระหว่างแคมเปญ
ข้อดีที่เห็นผลชัดเจน
เมื่อออกแบบและใช้งานอย่างเหมาะสม คุณจะได้ประโยชน์หลายด้าน เช่น
- หน้าเว็บลื่นขึ้น
- Primary มีทรัพยากรเหลือสำหรับงานเขียนมากขึ้น
- ลดโอกาส timeout เมื่อมีผู้ใช้งานพร้อมกันจำนวนมาก
- ขยายระบบได้ง่ายขึ้นในอนาคต
ข้อควรระวังที่ไม่ควรมองข้าม
แม้ Replica จะช่วยเรื่องประสิทธิภาพได้มาก แต่ก็มีเรื่องที่ต้องวางแผนไว้เสมอ เช่น
- Replica อาจล่มได้ จึงต้องมี fallback ให้กลับไปอ่านจาก Primary
- ข้อมูลที่ใหม่มากหรือสำคัญต่อธุรกรรม ไม่ควรพึ่ง Replica อย่างเดียว
- ต้องติดตาม replication lag อย่างต่อเนื่อง เพื่อให้รู้ว่าระบบยังตอบโจทย์ด้านความสดของข้อมูลหรือไม่
สรุป
Read Replica เป็นวิธีที่มีประสิทธิภาพในการลดภาระของฐานข้อมูลหลัก โดยแยกงานอ่านออกไปยังอีกเครื่องหรืออีกชุดหนึ่ง ช่วยให้เว็บไซต์รับมือกับทราฟฟิกสูงได้ดีขึ้นและลดความหน่วงของระบบ
อย่างไรก็ตาม หัวใจสำคัญไม่ได้อยู่ที่การเพิ่ม Replica เพียงอย่างเดียว แต่คือการออกแบบเส้นทางการอ่านเขียนให้เหมาะกับระดับความสดของข้อมูล หากใช้ร่วมกับ cache อย่าง Redis หรือ CDN ก็จะยิ่งช่วยให้ระบบนิ่งและลื่นขึ้นอย่างชัดเจนในช่วงที่ทราฟฟิกพุ่ง