Nỗi ám ảnh mang tên Master-Slave truyền thống
Mình từng thức trắng đêm vì một cụm MySQL chạy mô hình Master-Slave cho sàn thương mại điện tử gặp sự cố. Server Master đột ngột sập nguồn do lỗi phần cứng. Dù có Slave dự phòng, mình vẫn mất hơn 30 phút để kiểm tra độ lệch dữ liệu, thủ công chuyển Slave lên làm Master và cập nhật lại IP trong code ứng dụng. Với một hệ thống xử lý hàng trăm đơn hàng mỗi phút, 30 phút downtime là một thảm họa về doanh thu.
Rắc rối lớn nhất của replication kiểu cũ chính là tính thủ công. Khi có biến cố, bạn buộc phải can thiệp trực tiếp. Ngoài ra, rủi ro mất dữ liệu (data loss) luôn chực chờ vì cơ chế truyền tin không đồng bộ hoàn toàn. MySQL Group Replication (GR) xuất hiện để xóa bỏ nỗi lo này, mang đến khả năng tự phục hồi (Self-healing) thực thụ.
MySQL Group Replication hoạt động ra sao?
Về cơ bản, Group Replication là một plugin giúp các server MySQL phối hợp thành một khối thống nhất. Thay vì gửi dữ liệu một chiều, các node trong nhóm sẽ “thảo luận” với nhau qua giao thức đồng thuận Paxos.
Một giao dịch (transaction) chỉ được xác nhận thành công khi đa số các node trong nhóm đồng ý. Cách làm này mang lại hai giá trị cốt lõi:
- Tự động Failover: Nếu một node gặp sự cố, hệ thống tự bầu chọn leader mới trong chưa đầy 10 giây. Bạn không cần phải bật dậy giữa đêm để gõ lệnh nữa.
- Nhất quán dữ liệu: Loại bỏ tình trạng dữ liệu ảo hoặc mất transaction khi crash. Chỉ cần một node còn sống, dữ liệu của bạn vẫn an toàn.
Thực tế triển khai tại một hệ thống có database 200GB, mình nhận thấy latency tăng không đáng kể (thường dưới 5ms) nếu các node nằm trong cùng một khu vực (Region) có hạ tầng mạng ổn định.
Chuẩn bị môi trường thực chiến
Bạn cần tối thiểu 3 node để đảm bảo cơ chế bầu chọn đa số hoạt động ổn định. Trong hướng dẫn này, chúng ta sẽ sử dụng 3 VPS chạy MySQL 8.0 với các IP giả định:
- Node 1: 192.168.1.10 (mysql-1)
- Node 2: 192.168.1.11 (mysql-2)
- Node 3: 192.168.1.12 (mysql-3)
Lưu ý quan trọng: Group Replication yêu cầu mọi bảng phải sử dụng engine InnoDB và bắt buộc phải có Primary Key. Nếu thiếu khóa chính, các thao tác ghi dữ liệu sẽ bị GR từ chối ngay lập tức để bảo vệ tính nhất quán.
Bước 1: Tối ưu file cấu hình my.cnf
Trên cả 3 node, bạn hãy mở file cấu hình MySQL (thường tại /etc/mysql/mysql.conf.d/mysqld.cnf). Đây là khung xương để kích hoạt sức mạnh của Group Replication.
[mysqld]
# Định danh server (Node 1 là 1, Node 2 là 2...)
server_id = 1
binlog_format = ROW
log_slave_updates = ON
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
# Cấu hình Group Replication
transaction_write_set_extraction = XXH64
loose-group_replication_group_name = "550e8400-e29b-41d4-a716-446655440000"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "192.168.1.10:33061"
loose-group_replication_group_seeds = "192.168.1.10:33061,192.168.1.11:33061,192.168.1.12:33061"
loose-group_replication_bootstrap_group = OFF
# Chế độ Single Primary (Đảm bảo an toàn ghi dữ liệu)
loose-group_replication_single_primary_mode = ON
loose-group_replication_enforce_update_everywhere_checks = OFF
Hãy nhớ mở Firewall cho port 33061. Đây là kênh liên lạc riêng tư để các node “biết” được tình trạng sức khỏe của nhau.
Bước 2: Thiết lập User Replication
Sau khi khởi động lại MySQL, chúng ta cần tạo một “người đưa thư” chuyên trách việc đồng bộ. Đăng nhập vào MySQL trên cả 3 node và thực hiện:
SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'mat_khau_sieu_cap';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE REPLICATION SOURCE TO SOURCE_USER='repl', SOURCE_PASSWORD='mat_khau_sieu_cap' FOR CHANNEL 'group_replication_recovery';
Mẹo nhỏ: Lệnh SET SQL_LOG_BIN=0 giúp việc tạo user không bị ghi vào binlog. Điều này tránh gây xung đột dữ liệu khi các node bắt đầu bắt tay với nhau.
Bước 3: Khởi tạo Group (Bootstrapping)
Bạn chỉ thực hiện các lệnh dưới đây duy nhất trên Node 1. Đây là thao tác “khai sinh” ra group mới.
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;
Kiểm tra trạng thái bằng cách truy vấn bảng performance_schema.replication_group_members. Nếu cột MEMBER_STATE hiển thị ONLINE, group của bạn đã chính thức hoạt động.
Bước 4: Kết nối các Node còn lại
Việc gia nhập cho Node 2 và Node 3 đơn giản hơn nhiều. Bạn chỉ cần chạy các lệnh sau:
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
START GROUP_REPLICATION;
Hệ thống sẽ tự động đối chiếu dữ liệu hiện có với Node 1. Nếu có sự chênh lệch, các node mới sẽ tự kéo dữ liệu về cho đến khi đồng bộ hoàn toàn.
Kinh nghiệm thực chiến khi vận hành
Triển khai xong là một chuyện, vận hành ổn định lại là chuyện khác. Dưới đây là 3 lưu ý “xương máu” mà mình đúc kết được:
- Độ trễ mạng: GR cực kỳ nhạy cảm với network latency. Nếu ping giữa các node vượt quá 100ms, hệ thống có thể hiểu lầm là node đã chết và kick ra khỏi group liên tục.
- Kết hợp ProxySQL: Đừng để ứng dụng kết nối trực tiếp vào IP của MySQL. Hãy dùng ProxySQL để tự động điều hướng traffic Read/Write. Khi Master sập, ProxySQL sẽ tự nhận diện Master mới trong mili giây.
- Giới hạn Binlog: Đồng bộ liên tục khiến file binlog phình to rất nhanh. Bạn nên cấu hình
binlog_expire_logs_secondskhoảng 3-7 ngày để tránh tình trạng đầy ổ cứng đột ngột.
Lời kết
MySQL Group Replication không chỉ là một công nghệ, đó là sự yên tâm cho đội ngũ vận hành. Dù việc thiết lập ban đầu tốn sức hơn Master-Slave, nhưng khả năng tự phục hồi và bảo vệ dữ liệu là hoàn toàn xứng đáng. Nếu bạn đang quản lý hệ thống cần độ sẵn sàng 99.99%, hãy bắt tay vào thử nghiệm GR ngay hôm nay.
