Hướng dẫn cấu hình MySQL High Availability với Keepalived và HAProxy: Tự động chuyển đổi Virtual IP (VIP)

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

1. So sánh các mô hình High Availability (HA) cho MySQL

Chạy duy nhất một database server trên production là một quả bom nổ chậm. Chỉ cần ổ cứng quá tải, nghẽn mạng hay một lần restart để vá lỗi OS, toàn bộ dịch vụ sẽ tê liệt ngay. Để duy trì cam kết SLA 99.9% uptime, các team hạ tầng thường chọn một trong 4 phương án sau:

  • DNS Failover: Gán nhiều IP vào một bản ghi DNS và đổi IP khi có sự cố.
  • HAProxy đơn lẻ (Single LB): Dùng một máy chủ HAProxy đứng trước cụm MySQL để điều phối kết nối và kiểm tra health check.
  • Keepalived kết hợp HAProxy (Active-Passive với Virtual IP): Chạy 2 node HAProxy song song qua giao thức VRRP (Virtual Router Redundancy Protocol) để chia sẻ một Virtual IP (VIP). Khi node Active sập, VIP tự động nhảy sang node Passive.
  • MySQL InnoDB Cluster / Galera Cluster: Cụm đồng bộ Multi-Master, tự bầu chọn node mới ở tầng database engine.

2. Phân tích ưu và nhược điểm từng giải pháp

Không có giải pháp hoàn hảo, chỉ có giải pháp phù hợp với bài toán của bạn:

DNS Failover

  • Ưu điểm: Thiết lập cực nhanh, không cần cài thêm công cụ quản lý cluster phức tạp.
  • Nhược điểm: Phụ thuộc hoàn toàn vào TTL và DNS cache tại client. Khi server chết, thường mất 5–15 phút (thậm chí cả giờ với một số ISP) để client nhận IP mới. Hệ thống sẽ downtime kéo dài.

HAProxy đơn lẻ

  • Ưu điểm: Định tuyến thông minh, health check MySQL chính xác ở tầng TCP (Layer 4).
  • Nhược điểm: Tạo ra điểm nghẽn Single Point of Failure (SPOF). HAProxy sập thì toàn bộ ứng dụng mất kết nối, dù cụm MySQL phía sau vẫn sống khỏe.

MySQL InnoDB Cluster / Galera Cluster

  • Ưu điểm: Dữ liệu đồng bộ theo thời gian thực, đảm bảo tính nhất quán tuyệt đối giữa các node.
  • Nhược điểm: Vận hành rất phức tạp và tốn tài nguyên. Hệ thống dễ nghẽn deadlock khi lưu lượng ghi cao. Cần tối thiểu 3 node để chống hiện tượng split-brain.

Keepalived + HAProxy (Virtual IP)

  • Ưu điểm: Thời gian failover cực nhanh (dưới 1–2 giây). Giải quyết triệt để điểm lỗi đơn lẻ của HAProxy. Cực kỳ gọn nhẹ và tương thích hoàn hảo với mô hình MySQL Master-Replica truyền thống.
  • Nhược điểm: Hạ tầng mạng nội bộ cần hỗ trợ gói tin Multicast hoặc Unicast để giao thức VRRP hoạt động trơn tru.

3. Vì sao Keepalived + HAProxy là lựa chọn tối ưu cho hệ thống vừa và nhỏ?

Với hệ thống vừa và nhỏ, mô hình Keepalived + HAProxy mang lại hiệu quả vượt trội so với chi phí bỏ ra. Bạn không cần duy trì cụm cluster 3–5 node cồng kềnh. Toàn bộ backend chỉ cần kết nối tới một địa chỉ duy nhất: Virtual IP (VIP).

Hệ thống tự động lo việc giám sát node, chuyển hướng truy vấn và cô lập server hỏng. Trên thực tế, với hệ thống MySQL xử lý khoảng 1.500 QPS, kiến trúc này giúp failover chỉ trong ~800ms khi node chính gặp sự cố, loại bỏ hoàn toàn lỗi 502/504 phía người dùng.

4. Hướng dẫn triển khai từng bước

Kịch bản thực hành gồm 2 máy chủ Ubuntu/Debian trong cùng mạng LAN:

  • Node 1 (Primary LB / MySQL Master): IP 192.168.1.10
  • Node 2 (Backup LB / MySQL Replica): IP 192.168.1.11
  • Virtual IP (VIP chia sẻ): 192.168.1.100 (Ứng dụng kết nối vào IP này)

Bước 1: Tạo user kiểm tra sức khỏe trên MySQL

Đăng nhập vào MySQL trên cả 2 node để tạo user riêng cho HAProxy health check. User này không cần bất kỳ quyền truy cập dữ liệu nào:

mysql -u root -p -e "CREATE USER 'haproxy_check'@'%' IDENTIFIED BY ''; FLUSH PRIVILEGES;"

Bước 2: Cài đặt HAProxy, Keepalived và công cụ hỗ trợ

Chạy lệnh cài đặt trên cả 2 server:

sudo apt update
sudo apt install -y haproxy keepalived psmisc

Bước 3: Cấu hình HAProxy

Mở file /etc/haproxy/haproxy.cfg trên cả 2 node và cấu hình chuyển tiếp port 3306:

global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode tcp
    option tcplog
    option dontlognull
    retries 3
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend mysql_front
    bind *:3306
    mode tcp
    default_backend mysql_back

backend mysql_back
    mode tcp
    option mysql-check user haproxy_check
    server db01 192.168.1.10:3306 check inter 2000 rise 2 fall 3
    server db02 192.168.1.11:3306 check backup inter 2000 rise 2 fall 3

Khởi động và kích hoạt HAProxy tự chạy cùng hệ thống:

sudo systemctl restart haproxy
sudo systemctl enable haproxy

Bước 4: Cấu hình Keepalived quản lý Virtual IP

Trước tiên, cho phép kernel bind vào IP ảo ngay cả khi interface mạng chưa sở hữu IP đó:

echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Tạo script kiểm tra tiến trình HAProxy tại /usr/local/bin/check_haproxy.sh trên cả 2 máy:

cat << 'EOF' | sudo tee /usr/local/bin/check_haproxy.sh
#!/bin/bash
killall -0 haproxy
EOF

sudo chmod +x /usr/local/bin/check_haproxy.sh

Cấu hình Keepalived trên Node 1 (Master) tại /etc/keepalived/keepalived.conf:

vrrp_script check_haproxy {
    script "/usr/local/bin/check_haproxy.sh"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass SecretHAProxyPass123
    }

    virtual_ipaddress {
        192.168.1.100/24 dev eth0
    }

    track_script {
        check_haproxy
    }
}

Cấu hình Keepalived trên Node 2 (Backup) tại /etc/keepalived/keepalived.conf (hạ priority xuống 100):

vrrp_script check_haproxy {
    script "/usr/local/bin/check_haproxy.sh"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass SecretHAProxyPass123
    }

    virtual_ipaddress {
        192.168.1.100/24 dev eth0
    }

    track_script {
        check_haproxy
    }
}

Khởi động dịch vụ Keepalived trên cả hai máy:

sudo systemctl restart keepalived
sudo systemctl enable keepalived

Bước 5: Kiểm tra quá trình Failover thực tế

Kiểm tra IP hiện tại trên Node 1:

ip addr show eth0

Bạn sẽ thấy Virtual IP 192.168.1.100 đã được gán vào card mạng eth0 của Node 1. Bây giờ, giả lập sự cố bằng cách tắt service HAProxy trên Node 1:

sudo systemctl stop haproxy

Mở terminal của Node 2 và kiểm tra lại danh sách IP:

ip addr show eth0

Virtual IP 192.168.1.100 đã lập tức chuyển sang Node 2. Các ứng dụng kết nối tới 192.168.1.100:3306 tiếp tục gửi nhận query mà không cần can thiệp thủ công hay thay đổi cấu hình mã nguồn.

Share: