ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

ตั้ง MariaDB Galera Cluster สามโหนดที่เขียนได้ทุกเครื่อง
Home ตั้ง MariaDB Galera Cluster สามโหนดที่เขียนได้ทุกเครื่อง

ตั้ง MariaDB Galera Cluster สามโหนดที่เขียนได้ทุกเครื่อง

Galera Cluster ต่างจาก Replication แบบ Master-Replica ตรงที่ทุกโหนดรับการเขียนได้และข้อมูลตรงกันทุกโหนดก่อนที่จะตอบว่าสำเร็จ เมื่อโหนดใดล่ม ระบบยังทำงานต่อได้โดยไม่ต้องสลับตัวหลักด้วยมือ

ก่อนตัดสินใจใช้ ต้องรู้ข้อจำกัดสำคัญก่อน Galera รองรับเฉพาะ InnoDB ทุกตารางต้องมี Primary Key และการเขียนจะช้ากว่าเครื่องเดียวเพราะต้องยืนยันกับทุกโหนด จึงเหมาะกับระบบที่อ่านมากเขียนปานกลางและต้องการความพร้อมใช้งานสูง

สิ่งที่ต้องเตรียม

  • เซิร์ฟเวอร์สามเครื่อง ใช้จำนวนคี่เสมอเพื่อให้ตัดสินเสียงข้างมากได้
  • เครือข่ายภายในที่หน่วงต่ำระหว่างโหนด ยิ่งหน่วงสูงการเขียนยิ่งช้า
  • MariaDB 10.6 ขึ้นไป และสเปกที่เท่ากันทั้งสามเครื่อง

ในคู่มือนี้ใช้ IP 10.0.0.31, 10.0.0.32 และ 10.0.0.33

ขั้นตอนที่ 1: ติดตั้งบนทุกโหนด

sudo apt update
sudo apt install -y mariadb-server mariadb-client galera-4 rsync
sudo systemctl stop mariadb
sudo mysql_secure_installation

ขั้นตอนที่ 2: ตั้งค่าคลัสเตอร์

สร้างไฟล์เดียวกันบนทุกโหนด ต่างกันเฉพาะสองบรรทัดสุดท้าย

sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
[mysqld]
binlog_format = ROW
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
bind-address = 0.0.0.0

# Galera
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "tdc_cluster"
wsrep_cluster_address = "gcomm://10.0.0.31,10.0.0.32,10.0.0.33"
wsrep_sst_method = rsync
wsrep_slave_threads = 4

# เฉพาะโหนดนี้ แก้ให้ตรงกับแต่ละเครื่อง
wsrep_node_address = "10.0.0.31"
wsrep_node_name = "node1"

ค่า innodb_autoinc_lock_mode = 2 จำเป็นและห้ามเปลี่ยน Galera ต้องการค่านี้เพื่อให้เลขอัตโนมัติไม่ชนกันระหว่างโหนด

ขั้นตอนที่ 3: เปิด Firewall ระหว่างโหนด

sudo ufw allow from 10.0.0.0/24 to any port 3306 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4567
sudo ufw allow from 10.0.0.0/24 to any port 4568 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4444 proto tcp

พอร์ตแต่ละตัวมีหน้าที่ต่างกัน 3306 คือการใช้งานปกติ 4567 คือการสื่อสารของคลัสเตอร์ 4568 คือการส่งข้อมูลส่วนต่าง และ 4444 คือการถ่ายโอนข้อมูลตั้งต้นให้โหนดใหม่

ขั้นตอนที่ 4: เริ่มโหนดแรก

โหนดแรกต้องเริ่มด้วยคำสั่งพิเศษเพื่อสร้างคลัสเตอร์ขึ้นมา

sudo galera_new_cluster
sudo systemctl status mariadb --no-pager

mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
mysql -e "SHOW STATUS LIKE 'wsrep_local_state_comment';"

ควรเห็น wsrep_cluster_size เท่ากับ 1 และสถานะเป็น Synced

ใช้ galera_new_cluster เฉพาะครั้งแรกหรือเมื่อคลัสเตอร์หยุดทั้งหมดเท่านั้น การใช้ผิดจังหวะจะสร้างคลัสเตอร์ใหม่แยกออกไปและข้อมูลแตกเป็นสองชุด

ขั้นตอนที่ 5: เพิ่มโหนดที่สองและสาม

# บนโหนด 2 และ 3 ใช้คำสั่งเริ่มปกติ
sudo systemctl start mariadb
sudo journalctl -u mariadb -f

โหนดใหม่จะดึงข้อมูลทั้งหมดจากโหนดที่มีอยู่ ซึ่งใช้เวลาตามขนาดข้อมูล ระหว่างนี้จะเห็นสถานะ Joining และ Donor

ตรวจสอบเมื่อเสร็จ

mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"     # ควรเป็น 3
mysql -e "SHOW STATUS LIKE 'wsrep_cluster_status';"   # ควรเป็น Primary
mysql -e "SHOW STATUS LIKE 'wsrep_local_state_comment';" # ควรเป็น Synced
mysql -e "SHOW STATUS LIKE 'wsrep_incoming_addresses';"

ขั้นตอนที่ 6: ทดสอบว่าข้อมูลตรงกันทุกโหนด

# บนโหนด 1
mysql -e "CREATE DATABASE clustertest; CREATE TABLE clustertest.t (id INT PRIMARY KEY, v VARCHAR(50));"
mysql -e "INSERT INTO clustertest.t VALUES (1,'from node1');"

# บนโหนด 2 เขียนได้เช่นกัน
mysql -e "INSERT INTO clustertest.t VALUES (2,'from node2');"

# บนโหนด 3 ต้องเห็นทั้งสองแถว
mysql -e "SELECT * FROM clustertest.t;"

ทดสอบความทนทานด้วยการปิดโหนดหนึ่งแล้วดูว่าที่เหลือยังทำงาน

sudo systemctl stop mariadb   # บนโหนด 3
mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"  # ควรเหลือ 2 และยังเขียนได้
sudo systemctl start mariadb  # เปิดกลับ จะซิงก์เองอัตโนมัติ

ขั้นตอนที่ 7: กระจายการเชื่อมต่อจากแอป

แอปควรเชื่อมต่อผ่านตัวกระจายโหลด ไม่ใช่ชี้ตรงไปที่โหนดใดโหนดหนึ่ง ใช้ HAProxy ซึ่งเป็นวิธีที่นิยมที่สุด

sudo apt install -y haproxy
sudo nano /etc/haproxy/haproxy.cfg
listen galera
    bind 127.0.0.1:3307
    mode tcp
    balance first
    option tcpka
    server node1 10.0.0.31:3306 check weight 1
    server node2 10.0.0.32:3306 check backup
    server node3 10.0.0.33:3306 check backup

ใช้ balance first พร้อมกำหนดโหนดสำรอง แทนการกระจายการเขียนไปทุกโหนด เพราะการเขียนแถวเดียวกันจากหลายโหนดพร้อมกันทำให้เกิดข้อขัดแย้งที่ต้องยกเลิกทรานแซกชัน วิธีนี้ยังได้ความพร้อมใช้งานสูงโดยไม่มีข้อขัดแย้ง

ขั้นตอนที่ 8: กู้คืนเมื่อคลัสเตอร์หยุดทั้งหมด

เมื่อทุกโหนดดับพร้อมกัน เช่น ไฟดับทั้งศูนย์ ต้องหาว่าโหนดไหนมีข้อมูลใหม่ที่สุดแล้วเริ่มจากโหนดนั้น

# ตรวจบนทุกโหนด ดูค่า seqno ตัวที่มากที่สุดคือใหม่ที่สุด
sudo cat /var/lib/mysql/grastate.dat

หากค่า safe_to_bootstrap เป็น 1 บนโหนดใด ให้เริ่มจากโหนดนั้น

sudo galera_new_cluster

หากทุกโหนดเป็น 0 ให้เลือกโหนดที่ seqno สูงสุด แก้ไฟล์เป็น 1 แล้วค่อยเริ่ม

sudo nano /var/lib/mysql/grastate.dat   # แก้ safe_to_bootstrap: 1
sudo galera_new_cluster

จากนั้นเริ่มโหนดที่เหลือตามปกติ

ปัญหาที่พบบ่อย

โหนดใหม่เข้าคลัสเตอร์ไม่ได้

ตรวจพอร์ตทั้งสี่ตามขั้นตอนที่ 3 และดู Log ด้วย sudo journalctl -u mariadb -n 100 สาเหตุที่พบบ่อยคือ SELinux หรือ AppArmor บล็อก และ wsrep_cluster_address ที่พิมพ์ IP ผิด

ตารางไม่มี Primary Key

Galera ต้องการ Primary Key ทุกตาราง ตารางที่ไม่มีจะทำงานผิดพลาดแบบคาดเดาไม่ได้ ค้นหาด้วยคำสั่งตรวจสอบใน information_schema แล้วเพิ่มให้ครบก่อนใช้งานจริง

การเขียนช้ากว่าเครื่องเดียวมาก

เป็นธรรมชาติของระบบที่ต้องยืนยันกับทุกโหนด ตรวจความหน่วงของเครือข่ายด้วย ping ระหว่างโหนด หากเกิน 1 มิลลิวินาทีจะเห็นผลชัดเจน อย่าวางโหนดข้ามศูนย์ข้อมูลที่ไกลกัน

ขึ้น WSREP has not yet prepared node for application use

โหนดยังซิงก์ไม่เสร็จ รอจนสถานะเป็น Synced ตรวจความคืบหน้าด้วย SHOW STATUS LIKE 'wsrep_local_recv_queue';

ต้องการวางระบบฐานข้อมูลที่ไม่มีจุดตายเดียว ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security