Khi phần cứng “khủng” hoạt động kém hiệu quả
Tôi từng triển khai một API lưu lượng lớn trên một máy chủ sở hữu 16 nhân và 64GB RAM. Trên lý thuyết, đó là một “con quái vật”. Tuy nhiên, trong một đợt tăng vọt nhẹ với 5.000 người dùng đồng thời, ứng dụng bắt đầu xuất hiện lỗi “Connection Refused”. Các công cụ giám sát cho thấy CPU chỉ đang nghỉ ngơi ở mức 15% và còn rất nhiều bộ nhớ trống. Máy chủ không hề quá tải; nó chỉ đơn giản là bị bóp nghẹt bởi chính hệ điều hành của mình.
Sự ức chế này rất phổ biến đối với các nhà phát triển và quản trị hệ thống. Bạn có sức mạnh phần cứng thô, nhưng Kernel Linux lại đang chạy với các thiết lập mặc định “an toàn” dành cho máy tính để bàn thông thường. Để khai phá tiềm năng của phần cứng, bạn phải tìm hiểu về sysctl.
Vấn đề: Các thiết lập mặc định cũ kỹ trong thế giới hiện đại
Kernel Linux được thiết kế để hoạt động trên mọi thứ, từ Raspberry Pi đến siêu máy tính. Chính vì thế, các thiết lập mặc định của nó thường rất dè dặt. Mặc dù các thiết lập này đảm bảo sự ổn định trên một chiếc laptop cấu hình thấp, chúng lại trở thành nút thắt cổ chai cho một máy chủ production xử lý hàng nghìn yêu cầu mỗi giây.
Hầu hết các vấn đề về hiệu năng thường rơi vào ba nhóm sau:
- Network Backlogs: Hàng đợi cho các kết nối đến rất nhỏ (thường mặc định chỉ là 128). Điều này khiến kernel hủy bỏ (drop) các gói tin trước khi Nginx hoặc Node.js kịp nhận biết sự tồn tại của chúng.
- Socket Exhaustion: Hệ thống hết các cổng tạm thời (ephemeral ports). Điều này xảy ra khi nó giữ các kết nối đã đóng ở trạng thái “TIME_WAIT” trong 60 giây mặc định.
- Aggressive Swapping: Kernel chuyển dữ liệu sang ổ đĩa ngay cả khi RAM vẫn còn trống. Điều này có thể biến một truy vấn cơ sở dữ liệu 1ms thành một cơn ác mộng chờ đợi I/O đĩa 100ms.
Nâng cấp phần cứng hay Tối ưu hóa Kernel
Khi một trang web chậm lại, phản xạ tự nhiên là nhấn nút “Upgrade” trên bảng điều khiển đám mây. Mặc dù nhiều RAM hơn cung cấp nhiều không gian hoạt động hơn, nhưng nó hiếm khi khắc phục được một network stack bị cấu hình sai.
| Phương pháp | Ưu điểm | Nhược điểm |
|---|---|---|
| Mở rộng theo chiều dọc (Vertical Scaling) | Tăng tài nguyên tức thì. | Chi phí hàng tháng cao hơn; bỏ qua các nút thắt cổ chai phần mềm. |
| Cân bằng tải (Load Balancing) | Tuyệt vời cho sự dự phòng. | Tăng độ phức tạp kiến trúc và độ trễ. |
| Tối ưu hóa Kernel (sysctl) | Chi phí bằng không; tối đa hóa hiệu quả. | Yêu cầu thử nghiệm để tránh mất ổn định. |
Tối ưu hóa các tài nguyên hiện có là bước đi thông minh đầu tiên. Tinh chỉnh qua sysctl giúp loại bỏ sự ma sát giữa ứng dụng và phần cứng bên dưới.
Cách tiếp cận hệ thống với sysctl
Sau khi quản lý hàng chục cụm máy chủ production, tôi nhận thấy rằng một phương pháp có hệ thống sẽ tốt hơn là thay đổi thiết lập một cách bừa bãi. Một lỗi đánh máy nhỏ có thể gây ra lỗi kernel panic hoặc khiến bạn bị khóa quyền truy cập vào chính máy chủ của mình. Luôn thử nghiệm các thay đổi này trong môi trường staging trước.
1. Những điều cơ bản về sysctl
Lệnh sysctl sửa đổi các tham số kernel ngay khi hệ thống đang chạy. Các thiết lập này được tìm thấy trong thư mục /proc/sys/.
Để xem mọi thiết lập hiện tại trên hệ thống của bạn, hãy chạy:
sysctl -a
Để kiểm tra một giá trị cụ thể, chẳng hạn như số lượng tệp mở tối đa, hãy dùng:
sysctl fs.file-max
Nếu bạn muốn thử nghiệm một thay đổi mà không làm cho nó trở nên vĩnh viễn, hãy sử dụng cờ -w. Thiết lập này sẽ biến mất sau khi khởi động lại, đây là một “lưới an toàn” tuyệt vời.
2. Khắc phục Network Stack
Đối với các web server, network stack là nút thắt cổ chai thường gặp nhất. Nếu máy chủ của bạn xử lý nhiều kết nối ngắn hạn, bạn cần mở rộng “đường ống” và tái sử dụng các socket nhanh hơn.
Mở tệp cấu hình của bạn:
sudo nano /etc/sysctl.conf
Thêm các tham số này để xử lý lưu lượng truy cập có độ đồng thời cao:
# Tăng hàng đợi cho các kết nối đang chờ xử lý
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
# Mở thêm nhiều cổng cho các kết nối đi (mặc định thường là 32768-60999)
net.ipv4.ip_local_port_range = 1024 65535
# Tái sử dụng các socket ở trạng thái TIME_WAIT cho các kết nối mới
net.ipv4.tcp_tw_reuse = 1
# Ngắt kết nối nhanh hơn để giải phóng tài nguyên (mặc định là 60 giây)
net.ipv4.tcp_fin_timeout = 15
# Tăng kích thước cửa sổ TCP để có băng thông tốt hơn
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
3. Quản lý bộ nhớ và Swappiness
Theo mặc định, Linux bắt đầu chuyển dữ liệu từ RAM sang phân vùng Swap khi mức sử dụng RAM đạt khoảng 40%. Điều này cực kỳ tồi tệ đối với các cơ sở dữ liệu. Truy cập dữ liệu từ SSD hoặc HDD chậm hơn nhiều bậc so với RAM.
Đối với hầu hết các máy chủ production, tôi đặt swappiness là 10. Điều này yêu cầu kernel ưu tiên RAM và chỉ sử dụng ổ đĩa như một giải pháp cuối cùng.
vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2
Các thiết lập dirty_ratio kiểm soát cách kernel lưu dữ liệu vào bộ nhớ đệm trước khi ghi xuống đĩa. Giá trị cao hơn giúp cải thiện hiệu suất ghi nhưng làm tăng nguy cơ mất dữ liệu khi xảy ra sự cố mất điện.
4. Mở rộng giới hạn File Handle
Trong Linux, mỗi kết nối của người dùng, tệp nhật ký và socket đều là một file descriptor. Giới hạn mặc định thường là 1.024 cho mỗi tiến trình, mức mà một worker Nginx bận rộn có thể chạm tới chỉ trong vài giây.
fs.file-max = 2097152
Mặc dù fs.file-max đặt giới hạn toàn cục, hãy nhớ rằng bạn cũng có thể cần cập nhật /etc/security/limits.conf để nâng giới hạn cho từng người dùng đối với user chạy ứng dụng của bạn.
5. Áp dụng các thay đổi
Sau khi bạn đã cập nhật /etc/sysctl.conf, hãy áp dụng các thay đổi ngay lập tức với:
sudo sysctl -p
Luôn kiểm tra lại để đảm bảo các giá trị đã có hiệu lực. Ví dụ, chạy sysctl net.core.somaxconn để xác minh giới hạn 65535 mới đang hoạt động.
Quy trình làm việc an toàn
Đừng chỉ sao chép và dán một tệp cấu hình khổng lồ. Hãy làm theo quy trình sau để giữ cho môi trường của bạn ổn định:
- Baseline (Điểm chuẩn): Chạy một bài kiểm tra tải bằng
wrkhoặck6để đo lường băng thông và tỷ lệ lỗi hiện tại. - Iterate (Lặp lại): Thay đổi từng nhóm thiết lập một (ví dụ: chỉ phần Mạng).
- Watch (Theo dõi): Theo dõi
dmesghoặc/var/log/syslogđể tìm bất kỳ cảnh báo hoặc lỗi kernel nào. - Verify (Xác minh): Chạy lại bài kiểm tra tải. Bạn sẽ thấy lỗi kết nối giảm xuống và thời gian phản hồi ổn định hơn.
Tối ưu hóa kernel không phải là phép thuật, nhưng nó mang lại cảm giác giống như vậy. Nhìn thấy một máy chủ xử lý lượng truy cập gấp đôi với cùng mức sử dụng CPU là một trải nghiệm cực kỳ thỏa mãn. Hãy bắt đầu với somaxconn và swappiness—chỉ riêng hai thay đổi này đã mang lại hiệu quả lớn nhất cho hầu hết các khối lượng công việc.

