Câu chuyện chiếc Ferrari chạy trong ngõ nhỏ
Tôi từng xử lý hệ thống log cho một sàn thương mại điện tử lớn với lưu lượng khoảng 50.000 request/giây. Khi hệ thống nghẽn I/O, sếp đã chi hàng nghìn USD nâng cấp sang dàn NVMe Samsung Enterprise. Cả team đều đinh ninh tốc độ sẽ tăng vọt vì thông số IOPS của NVMe cao gấp hàng chục lần SSD SATA cũ.
Thực tế lại là một gáo nước lạnh. Sau khi chuyển data, chỉ số iowait vẫn đỏ rực, ứng dụng vẫn phản hồi chậm chạp. Hóa ra, cài đặt MySQL mặc định giống như việc bạn lái Ferrari trong ngõ nhỏ với giới hạn 20km/h. Nếu không biết cách “mở khóa”, phần cứng xịn đến mấy cũng chỉ để làm cảnh.
Tại sao MySQL mặc định lại làm phí tiền mua ổ NVMe?
Lý do rất đơn giản: Các tham số mặc định của InnoDB được viết từ thời ổ cứng HDD còn thống trị.
- Giới hạn IOPS quá thấp:
innodb_io_capacitymặc định chỉ là 200. Trong khi đó, một ổ NVMe tầm trung hiện nay dễ dàng đạt 300.000 – 500.000 IOPS. - Cơ chế Flush lỗi thời: Cách InnoDB đẩy dữ liệu xuống đĩa quá rụt rè, khiến ổ cứng thì ngồi chơi mà CPU lại phải chờ đợi I/O.
- Hàng đợi Kernel: Linux mặc định thường cố gắng sắp xếp các yêu cầu I/O để tối ưu cho đầu đọc cơ học, điều này hoàn toàn thừa thãi với chip nhớ NVMe.
Bước 1: Ép InnoDB phải làm việc hết công suất
Mở file my.cnf lên. Đây là nơi bạn giải phóng sức mạnh cho phần cứng.
Cấu hình innodb_io_capacity
Tham số này định nghĩa khả năng xử lý I/O của hệ thống lưu trữ. Với NVMe, hãy mạnh dạn tăng con số này lên. Đừng dùng mức 200 yếu ớt nữa.
[mysqld]
# Với ổ NVMe đơn lẻ (ví dụ Samsung 980 Pro/PM9A1)
innodb_io_capacity = 5000
innodb_io_capacity_max = 10000
# Nếu chạy RAID 0 NVMe hoặc dòng chuyên dụng Enterprise
# innodb_io_capacity = 20000
# innodb_io_capacity_max = 40000
Tắt tính năng innodb_flush_neighbors
Trên HDD, việc ghi các block dữ liệu liền kề giúp giảm quãng đường di chuyển của đầu đọc. Với NVMe, việc này chỉ làm tốn tài nguyên CPU vô ích. Hãy tắt nó ngay lập tức.
innodb_flush_neighbors = 0
Sử dụng innodb_flush_method = O_DIRECT
Mặc định, dữ liệu bị cache hai lần tại InnoDB Buffer Pool và OS Page Cache. O_DIRECT giúp MySQL ghi thẳng xuống ổ đĩa, giải phóng RAM và giảm độ trễ ghi xuống mức tối thiểu.
innodb_flush_method = O_DIRECT
Bước 2: Tinh chỉnh Linux Kernel để “mở đường” cho dữ liệu
Hệ điều hành là cầu nối giữa MySQL và phần cứng. Nếu cầu hẹp, xe dù mạnh cũng không thể đi nhanh.
Thay đổi I/O Scheduler
Các scheduler như cfq hay deadline sinh ra để phục vụ ổ đĩa quay. Với NVMe, bạn nên chuyển sang none để bỏ qua lớp sắp xếp trung gian của Kernel, giúp giảm latency đáng kể.
# Kiểm tra (thay nvme0n1 bằng tên ổ thực tế của bạn)
cat /sys/block/nvme0n1/queue/scheduler
# Chuyển sang none để đạt tốc độ cao nhất
echo none > /sys/block/nvme0n1/queue/scheduler
Tăng hàng đợi nr_requests
NVMe cực giỏi trong việc xử lý song song. Hãy cho phép hệ điều hành đẩy nhiều yêu cầu hơn vào hàng đợi cùng một lúc.
echo 1024 > /sys/block/nvme0n1/queue/nr_requests
Cấu hình Mount noatime
Mỗi khi bạn SELECT, Linux mặc định sẽ ghi lại thời gian truy cập file. Với database, việc này cực kỳ lãng phí. Thêm noatime vào /etc/fstab để triệt tiêu các thao tác ghi thừa này.
/dev/nvme0n1p1 /var/lib/mysql ext4 defaults,noatime 0 2
Lỗi kinh điển: Quên cấu hình innodb_log_file_size
Tôi từng gặp trường hợp dù đã tối ưu I/O cực tốt nhưng tốc độ ghi vẫn bị khựng mỗi 5 phút. Sau khi kiểm tra, thủ phạm là innodb_log_file_size chỉ để 128MB.
Khi file log đầy, MySQL sẽ dừng mọi hoạt động để thực hiện checkpoint. Với NVMe, bạn nên để log file tối thiểu 1GB – 2GB. Điều này giúp kéo dài khoảng cách giữa các lần checkpoint, giúp hiệu năng ổn định hơn dưới tải cao.
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
Tối ưu hóa là một hành trình, không phải đích đến
Đừng copy paste mọi thông số vào server production ngay. Hãy thực hiện theo quy trình 4 bước:
- Benchmark: Dùng
fiođo IOPS thực tế của ổ cứng trước khi cấu hình. - Tinh chỉnh Kernel: Ưu tiên
nonescheduler vànoatime. - Cấu hình MySQL: Tập trung vào
io_capacityvàO_DIRECT. - Giám sát: Chạy
iostat -x 1. Nếu cột%utildưới 60% mà ứng dụng vẫn chậm, bạn vẫn còn dư địa để tănginnodb_io_capacity.
Cấu hình mặc định là kẻ thù của hiệu năng. Hãy mạnh dạn thay đổi để tận dụng từng đồng chi phí bạn đã bỏ ra cho ổ NVMe. Kết quả phản hồi từ ứng dụng sẽ chứng minh bạn đúng!

