MySQL Router: ‘Chốt chặn’ giúp InnoDB Cluster tự động Failover và sống sót qua sự cố

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

Vấn đề: Ác mộng 2 giờ sáng và cái giá của sự thủ công

Hãy tưởng tượng kịch bản này: 2 giờ sáng, điện thoại reo liên hồi. Hệ thống giám sát báo lỗi 500 hàng loạt, Database mất kết nối hoàn toàn. Bạn bật dậy, kiểm tra thì thấy node Primary của MySQL InnoDB Cluster bị treo cứng do nghẽn I/O. Theo lý thuyết, cụm Cluster sẽ tự bầu chọn một node khác lên làm Primary. Thế nhưng, App của bạn vẫn đang “cố đấm ăn xôi” kết nối vào IP của node cũ đã chết.

Kết quả là bạn phải lọ mọ sửa file .env cho hàng chục microservices để trỏ sang IP mới rồi restart từng cái. Cảm giác lúc đó cực kỳ ức chế vì rõ ràng chúng ta đã có Cluster nhưng vẫn phải xử lý bằng tay. Sai lầm nằm ở việc để App kết nối trực tiếp vào một node DB đơn lẻ. Để giải quyết triệt để, chúng ta cần một lớp điều phối thông minh: MySQL Router.

Trước đây, khi bảng users hệ thống bên mình vượt ngưỡng 20 triệu bản ghi, các truy vấn chậm (slow query) bắt đầu xuất hiện dày đặc. Tối ưu index hay code là chưa đủ. Nếu hạ tầng thiếu khả năng tự phục hồi (Self-healing), mọi nỗ lực tối ưu sẽ đổ sông đổ biển ngay khi một thanh RAM hay ổ cứng gặp sự cố.

Khái niệm cốt lõi: MySQL Router đóng vai trò gì?

MySQL Router giống như một trạm kiểm soát không lưu đứng giữa Application và cụm InnoDB Cluster. Thay vì bắt App phải nhớ danh sách IP của từng node, bạn chỉ cần cung cấp một địa chỉ duy nhất của Router.

  • Metadata Cache (Tự nhận diện): Router liên tục kết nối với Cluster để nắm bắt trạng thái các node. Nó biết chính xác đâu là Primary (Read-Write) và đâu là các Secondary (Read-Only).
  • Điều hướng thông minh: Các truy vấn ghi dữ liệu được Router đẩy thẳng sang node Primary. Trong khi đó, các truy vấn đọc được phân phối đều sang các node Secondary để giảm tải cho node chính.
  • Trong suốt với App: Khi một node DB gặp sự cố, Router tự động gạch tên nó khỏi danh sách điều hướng. App của bạn không hề hay biết về sự thay đổi này; không cần sửa config, cũng chẳng cần restart.

Thực hành: Cài đặt và cấu hình MySQL Router

Thông thường, mình sẽ cài MySQL Router ngay trên máy chủ chạy App để tối ưu độ trễ (latency) xuống mức thấp nhất (thường dưới 1ms). Dưới đây là các bước triển khai thực tế.

1. Cài đặt nhanh

Trên Ubuntu/Debian, bạn chỉ cần tận dụng repository chính thức của MySQL:

sudo apt-get update
sudo apt-get install mysql-router

Với anh em dùng CentOS/RHEL, lệnh cài đặt cũng rất gọn:

sudo yum install mysql-router

2. Khởi tạo (Bootstrap) tự động

Đừng ngồi viết file cấu hình thủ công vì rất dễ sai sót. Hãy sử dụng lệnh --bootstrap để Router tự kết nối vào Cluster và lấy mọi thông tin cần thiết.

mysqlrouter --bootstrap [email protected]:3306 --user mysqlrouter

Trong đó:

  • cluster_admin: Tài khoản có quyền quản trị cụm.
  • 192.168.1.10:3306: IP của bất kỳ node nào đang sống trong cụm.

Sau khi xác nhận mật khẩu, Router sẽ mở ra hai cổng kết nối cực kỳ quan trọng:

  • Port 6446: Cổng ưu tiên ghi (Read-Write), luôn trỏ tới node Primary hiện tại.
  • Port 6447: Cổng ưu tiên đọc (Read-Only), tự động cân bằng tải giữa các node Secondary.

3. Vận hành Service

Hãy đảm bảo Router luôn chạy cùng hệ thống bằng cách kích hoạt service:

sudo systemctl start mysqlrouter
sudo systemctl enable mysqlrouter

4. Cập nhật Application

Bước cuối cùng là thay đổi thông tin kết nối trong file .env. Thay vì trỏ đến IP của Database, hãy trỏ về Localhost nếu bạn cài Router cùng máy với App.

# Cấu hình cũ (Rủi ro downtime cao)
DB_HOST=192.168.1.10
DB_PORT=3306

# Cấu hình mới (Tự động failover)
DB_HOST=127.0.0.1
DB_PORT=6446

Kiểm chứng: Khi sự cố xảy ra

Để thực sự yên tâm, bạn nên thử nghiệm giả lập lỗi. Hãy thử dừng service MySQL trên node Primary hiện tại bằng lệnh systemctl stop mysql. Ngay lập tức, hãy theo dõi log của Router:

tail -f /var/log/mysqlrouter/mysqlrouter.log

Bạn sẽ thấy Router nhận ra Primary đã chết. Nó sẽ đợi Cluster bầu ra leader mới (quá trình này thường chỉ mất 10-20 giây). Sau đó, nó tự cập nhật Metadata và điều hướng mọi kết nối từ port 6446 sang IP mới. Hệ thống chỉ gián đoạn trong tích tắc thay vì downtime cả tiếng đồng hồ.

Lời kết

Sử dụng MySQL Router không chỉ là vấn đề kỹ thuật, mà là mua lấy sự an tâm. Với mức tiêu thụ tài nguyên cực thấp (thường dưới 100MB RAM), đây là khoản đầu tư quá rẻ cho tính ổn định của hệ thống. Hãy nhớ: Một cụm Cluster mà không có Router thì mới chỉ đi được nửa chặng đường của High Availability mà thôi.

Share: