mysqlslap: Cách mình “tra tấn” MySQL để tìm giới hạn chịu tải thực tế

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

Cú sốc khi hệ thống “ngỏm” ngay giờ G

Sáu tháng trước, mình từng “toát mồ hôi hột” khi vận hành chiến dịch Flash Sale cho một sàn TMĐT. Ở môi trường staging, mọi thứ chạy cực ổn với độ trễ chỉ 10-20ms. Mình tự tin khẳng định với sếp: “Hệ thống cân tốt anh ạ”.

Nhưng thực tế lại tạt gáo nước lạnh vào mặt mình. Đúng 0h, traffic tăng vọt gấp 20 lần. Table orders với 12 triệu bản ghi bắt đầu “đứng hình”. CPU server chạm ngưỡng 98%, RAM cạn kiệt và hàng loạt request nhận lỗi 504 Gateway Timeout. Bài học rút ra rất đắt giá: Chạy đúng tính năng không có nghĩa là chịu tải được.

Tại sao test thủ công luôn khiến bạn lầm tưởng?

Sai lầm lớn nhất của mình là chỉ dùng MySQL Workbench chạy vài câu EXPLAIN đơn lẻ. Chạy một câu SQL khi chỉ có mình bạn “độc chiếm” database khác xa với việc 500 người cùng click “Thanh toán” trong 1 giây. Lúc này, tranh chấp tài nguyên mới là kẻ thù thực sự.

Khi mổ xẻ vấn đề, mình nhận ra ba “hung thủ” chính:

  • Connection Overhead: Việc mở/đóng 2.000 kết nối mỗi phút làm RAM kiệt quệ nhanh chóng.
  • Lock Contention: Các lệnh Update tranh chấp row-level lock, khiến hàng đợi dài dằng dặc.
  • Disk I/O: Cache bị tràn, buộc MySQL phải đọc dữ liệu từ ổ cứng với tốc độ rùa bò.

Chọn công cụ benchmark: Mạnh thôi chưa đủ, phải nhanh

Để không lặp lại sai lầm, mình bắt đầu tìm kiếm công cụ kiểm thử. JMeter quá cồng kềnh cho nhu cầu test nhanh query. Sysbench rất mạnh nhưng cấu hình phức tạp, tốn cả buổi chỉ để setup môi trường.

Cuối cùng, mình chọn mysqlslap. Đây là công cụ có sẵn ngay khi bạn cài MySQL, cực kỳ gọn nhẹ và thực dụng.

Làm chủ mysqlslap trong 5 phút

mysqlslap giúp bạn giả lập hàng trăm user “nã” query vào server cùng lúc. Bạn sẽ biết chính xác server sẽ trụ được bao lâu trước khi sập.

1. Kiểm tra sức khỏe tổng quát

Để test nhanh mà không cần chuẩn bị database, mình dùng lệnh sau:

mysqlslap --user=root --password --auto-generate-sql --concurrency=100 --iterations=5

Trong đó, --concurrency=100 giả lập 100 user truy cập cùng lúc. Mình lặp lại 5 lần (--iterations=5) để lấy con số trung bình chính xác nhất, loại bỏ các sai số do OS background task.

2. Test với dữ liệu thực tế

Sau khi test tổng quát, mình lôi các câu lệnh “ngốn” tài nguyên từ Slow Query Log ra để thử thách server. Giả sử mình cần test một câu JOIN phức tạp trên database production_copy:

mysqlslap --user=root --password \
--concurrency=30 --iterations=3 \
--query="SELECT * FROM orders JOIN users ON orders.user_id = users.id WHERE orders.status = 'pending';" \
--create-schema=inventory_db

Lệnh này giúp mình biết liệu khi có 30 người cùng xem báo cáo, hệ thống có bị lag hay không.

3. Giả lập tải hỗn hợp (Đọc và Ghi)

Trong thực tế, không bao giờ chỉ có người xem (Read). Luôn có người mua hàng (Write). Mình thường dùng option mixed để mô phỏng kịch bản này:

mysqlslap --user=root --password --concurrency=80 --iterations=5 \
--auto-generate-sql --auto-generate-sql-load-type=mixed

Lúc này, mysqlslap sẽ trộn lẫn INSERT và SELECT. Đây là cách tốt nhất để phát hiện ra các vấn đề về Lock Table.

Cách đọc kết quả để không bị “con số” lừa dối

Sau khi chạy, bạn sẽ nhận được bảng thống kê thời gian thực thi (Average, Minimum, Maximum). Đừng chỉ nhìn vào con số trung bình.

Nếu Average time tăng từ 0.5s lên 5s khi bạn nâng concurrency từ 50 lên 100, đó là tín hiệu đỏ. Server của bạn đã chạm ngưỡng giới hạn CPU.

Kinh nghiệm của mình với table 12 triệu row: Sau khi thêm Index, thời gian chạy trung bình giảm từ 3.2s xuống còn 0.15s. Chỉ khi thấy con số này ổn định qua 10 lần test, mình mới dám deploy lên production.

Lưu ý để không phải restore database trong đêm

Sử dụng mysqlslap giống như dùng dao hai lưỡi. Tuyệt đối không chạy tool này trực tiếp trên server Production đang phục vụ người dùng. Nó tạo ra tải cực lớn và có thể tự tay làm sập web của bạn ngay lập tức.

Hãy luôn test trên một bản sao (Clone) có cấu hình phần cứng tương đương. Kết quả trên con Macbook i7 của bạn sẽ khác xa với một con Cloud Server 2 vCPU giá 10$/tháng.

Tóm lại, thay vì ngồi cầu nguyện hệ thống không sập, hãy chủ động “ép xung” nó bằng mysqlslap. Chúc các bạn tối ưu database thành công!

Share: