Database
น้องๆ เคยสงสัยมั้ยว่าทำไม Facebook หรือ Google ถึงไม่เคยล่มเลย? (หรือล่มน้อยมาก) หนึ่งในเคล็ดลับคือ Database Replication นี่แหละ! สมัยผมทำร้านเน็ต SiamCafe.net เมื่อ 20 กว่าปีก่อน ถ้า Database ล่มทีนี่ลูกค้าโวยวายกันตรึมเลยนะ เพราะ login ไม่ได้ เล่นเกมไม่ได้ ชีวิตวุ่นวายสุดๆ
Database Replication แบบ Master-Slave คือการที่เรามี Database หลัก (Master) ที่รับคำสั่งเขียน (Write) และอ่าน (Read) ทั้งหมด แล้วเราก็ทำการสำเนา (Replicate) ข้อมูลจาก Master ไปยัง Database รอง (Slave) หลายๆ ตัว หน้าที่หลักของ Slave คือ อ่านข้อมูล (Read-Only) อย่างเดียว
ทำไมถึงสำคัญน่ะเหรอ? ลองนึกภาพว่า Master ของเราเกิดไฟไหม้ (สมมติเฉยๆ นะ!) หรือมีคนมือบอนไป Drop Table เล่นๆ ถ้าไม่มี Slave ข้อมูลทุกอย่างก็หายวับไปกับตา แต่ถ้ามี Slave เราก็แค่ยก Slave ตัวใดตัวหนึ่งขึ้นมาเป็น Master แทน ข้อมูลก็ยังอยู่ครบ!
ก่อนจะไปลงมือทำจริงๆ เราต้องเข้าใจพื้นฐานกันก่อนนะ ไม่งั้นทำไปก็งงเปล่าๆ เหมือนสมัยผมหัดเขียน Perl ใหม่ๆ อะไรก็มั่วไปหมด ฮ่าๆ
Transaction คือชุดคำสั่งที่เรามองว่าเป็นหน่วยเดียวกัน ถ้าคำสั่งใดคำสั่งหนึ่งในชุดนั้นล้มเหลว ทุกอย่างต้อง Rollback กลับไปเหมือนเดิม เช่น การโอนเงินจากบัญชี A ไปบัญชี B ต้องทำทั้งหักเงินจาก A และเพิ่มเงินให้ B ถ้าหักเงินจาก A ไปแล้ว แต่เพิ่มเงินให้ B ไม่ได้ เงินก็ต้องกลับไปอยู่ที่ A เหมือนเดิม
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';
COMMIT;
ACID ย่อมาจาก Atomicity, Consistency, Isolation, Durability เป็นคุณสมบัติที่ Transaction ต้องมี
ถ้าอยากรู้เรื่อง ACID Properties แบบละเอียด ลองไปอ่านที่ SiamCafe Blog นะ ผมเคยเขียนไว้ละเอียดมาก
เอาล่ะ! มาถึงส่วนที่สนุกที่สุดแล้ว นั่นคือการลงมือทำจริง! สมัยผมทำร้านเน็ตเนี่ย ผมใช้ MySQL เป็นหลัก ดังนั้นตัวอย่างที่จะยกก็จะเป็น MySQL นะ แต่หลักการก็คล้ายๆ กันกับ Database ตัวอื่นๆ
อันดับแรก เราต้องเข้าไปแก้ Configuration File ของ MySQL (ส่วนใหญ่จะอยู่ที่ /etc/mysql/my.cnf หรือ /etc/my.cnf) แล้วเพิ่มหรือแก้ไข Config เหล่านี้
[mysqld]
server-id = 1 # ID ของ Master Server (ต้องไม่ซ้ำกับ Slave)
log_bin = mysql-bin # เปิด Binary Logging
binlog_do_db = your_database_name # Database ที่ต้องการ Replicate
อย่าลืม Restart MySQL Server หลังจากแก้ Config นะ
ทำเหมือน Master เลย แต่เปลี่ยน server-id เป็นเลขอื่น (เช่น 2, 3, 4) และเพิ่ม Config เกี่ยวกับการเชื่อมต่อกับ Master
[mysqld]
server-id = 2 # ID ของ Slave Server
relay_log = mysql-relay-bin # Relay Log สำหรับเก็บ Binary Log จาก Master
relay_log_index = mysql-relay-bin.index
log_error = /var/log/mysql/slave.log # Log file สำหรับ Slave
master_host = your_master_ip # IP Address ของ Master Server
master_user = replication_user # User ที่มีสิทธิ์ Replicate
master_password = your_password # Password ของ User
master_log_file = mysql-bin.000001 # Binary Log File ที่ Slave จะเริ่มอ่าน
master_log_pos = 4 # ตำแหน่งใน Binary Log File ที่ Slave จะเริ่มอ่าน
replicate_do_db = your_database_name # Database ที่ต้องการ Replicate
master_log_file และ master_log_pos คือค่าที่เราต้องไปเอามาจาก Master Server โดยใช้คำสั่ง SHOW MASTER STATUS;
หลังจากแก้ Config และ Restart MySQL Server บน Slave แล้ว เราก็ต้องสั่งให้ Slave เริ่มทำงาน
START SLAVE;
SHOW SLAVE STATUS\G
ถ้าทุกอย่างถูกต้อง Slave Status ควรจะแสดงว่า Slave กำลังเชื่อมต่อกับ Master และกำลัง Replicate ข้อมูลอยู่ ถ้ามี Error ก็ต้องไปดูที่ Slave Log File (/var/log/mysql/slave.log) เพื่อหาสาเหตุ
ถ้าอยากรู้เรื่อง MySQL แบบ Advance ลองไปอ่านที่ SiamCafe Blog นะ ผมเขียนไว้เยอะมาก ตั้งแต่ Beginner ยัน Expert
Master-Slave ไม่ใช่ทางเลือกเดียวในการทำ Database Replication นะ ยังมีทางเลือกอื่นๆ อีก เช่น Master-Master Replication, Clustering, และ Sharding แต่ละแบบก็มีข้อดีข้อเสียต่างกันไป
| เทคนิค | ข้อดี | ข้อเสีย |
|---|---|---|
| Master-Slave Replication | ง่ายต่อการตั้งค่า, เหมาะกับการอ่านข้อมูลเยอะๆ | Master เป็น Single Point of Failure, เขียนข้อมูลได้ที่ Master เท่านั้น |
| Master-Master Replication | เขียนข้อมูลได้ที่ Server ไหนก็ได้, High Availability | ซับซ้อนกว่า, อาจเกิด Conflict ของข้อมูลได้ |
| Clustering | High Availability, Scalability | ซับซ้อน, ต้องการ Hardware ที่ดี |
| Sharding | Scalability, แบ่งข้อมูลตาม Logic ได้ | ซับซ้อน, การ Query ข้าม Shard ยาก |
เลือกใช้เทคนิคไหนก็ขึ้นอยู่กับความต้องการและงบประมาณของแต่ละคน สมัยผมทำร้านเน็ต ผมใช้ Master-Slave เป็นหลัก เพราะง่ายและตอบโจทย์เรื่อง Read-Heavy Workload ได้ดี แต่ถ้าเป็นระบบใหญ่ๆ อย่าง Facebook หรือ Google เขาอาจจะใช้หลายๆ เทคนิครวมกันเพื่อประสิทธิภาพสูงสุด
เฮ้ น้องๆ สมัยผมทำร้านเน็ต SiamCafe เนี่ย เรื่อง Database Replication นี่สำคัญมากนะ เพราะถ้า Database หลักล่มขึ้นมา ชีวิตจบเห่เลย ลูกค้าเล่นเกมส์ไม่ได้ จ่ายเงินไม่ได้ ผมเลยต้องหาทางทำให้มันเสถียรที่สุดเท่าที่จะทำได้
จำไว้เลยว่า Replication ไม่ใช่ยาวิเศษ มันต้องมีการวางแผนและการดูแลอย่างดี มาดูกันว่ามีอะไรบ้างที่ผมอยากแนะนำจากประสบการณ์ตรง
สมัยก่อนเครื่องไม้เครื่องมือมันไม่ได้ดีเหมือนสมัยนี้ แต่ผมก็พยายามหาทาง Monitoring Replication Status ให้ได้มากที่สุดเท่าที่จะทำได้ เขียน Script ง่ายๆ เช็ค Lag Time (ความต่างของข้อมูลระหว่าง Master กับ Slave) ถ้ามันเริ่มเยอะผิดปกติ ต้องรีบเข้าไปดูเลย
#!/bin/bash
mysql -u root -p'your_password' -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master
Code snippet ด้านบนเป็นแค่ตัวอย่างง่ายๆ นะ เอาไปปรับใช้ให้เข้ากับ Monitoring Tools ที่น้องๆ ใช้กันอยู่ได้เลย
ถึงจะมี Replication แล้ว ก็อย่าลืม Backup Database เป็นประจำนะ! Replication มันช่วยเรื่อง High Availability แต่ไม่ได้ช่วยเรื่อง Data Corruption หรือ Human Error ถ้าเผลอไป Drop Table ใน Master ขึ้นมา Backup นี่แหละที่จะช่วยชีวิตน้องๆ ได้
อย่ารอให้ Master พังแล้วค่อยมาลอง Failover เป็น Slave เป็น Master นะ! ต้องมีการ Test Failover เป็นประจำ เพื่อให้แน่ใจว่า Process มันถูกต้อง และทีมงานทุกคนรู้วิธีการทำจริงๆ
Query ที่ช้าใน Master ก็จะช้าใน Slave ด้วย เพราะฉะนั้นต้อง Optimize Queries ให้ดี ทั้งใน Master และ Slave เพื่อให้ Replication ทำงานได้เร็วและมีประสิทธิภาพ
Lag เกิดได้จากหลายสาเหตุ เช่น Network Congestion, Slow Queries, Hardware Resource ไม่พอ ลองไล่เช็คทีละอย่างดูนะ
ง่ายๆ เลย Master จะบันทึกทุกการเปลี่ยนแปลง (Write) ลงใน Binary Log แล้ว Slave ก็จะอ่าน Binary Log นี้ไป Apply ลงใน Database ของตัวเอง
ได้! เราสามารถใช้ Slave เป็น Read Replica เพื่อแบ่ง Load ในการอ่านข้อมูลได้ แต่ต้องระวังเรื่อง Data Consistency ด้วยนะ
ได้แน่นอน! ถ้า Master พัง เราก็สามารถ Promote Slave ขึ้นมาเป็น Master แทนได้ แต่ต้องมีการวางแผนและเตรียมการให้พร้อม
Database Replication เป็นเครื่องมือที่ทรงพลัง แต่ก็ต้องใช้ด้วยความระมัดระวัง ต้องมีการวางแผนที่ดี Monitoring อย่างสม่ำเสมอ และ Test Failover เป็นประจำ ถึงจะมั่นใจได้ว่าระบบของเราจะเสถียรและพร้อมรับมือกับทุกสถานการณ์
อย่าลืมแวะไปอ่านบทความอื่นๆ ใน SiamCafe Blog นะ มีเรื่อง IT สนุกๆ อีกเยอะเลย
ถ้าสนใจเรื่อง Forex ลองดู iCafeForex ได้นะ