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.

