Thực trạng nghẽn cổ chai 10Gbps
Bạn đã bao giờ cắm một module SFP+ cao cấp vào máy chủ và mong đợi một luồng dữ liệu 10Gbps rực rỡ, nhưng rồi lại thấy nó lẹt đẹt ở mức 4.2Gbps chưa? Tôi đã từng gặp trường hợp đó. Nhìn một nhân CPU nhảy vọt lên 100% trong khi phần còn lại của hệ thống nhàn rỗi là một lời cảnh tỉnh gây ức chế. Mạng tốc độ cao trên Linux không phải là trải nghiệm “cắm là chạy”; nó đòi hỏi hệ điều hành phải nhanh tương xứng với các sợi cáp quang truyền tải dữ liệu.
Các bản phân phối Linux tiêu chuẩn thường ưu tiên khả năng tương thích. Chúng đi kèm với các cài đặt được tối ưu hóa cho mạng LAN văn phòng 1Gbps hoặc kết nối gia đình. Khi bạn nâng cấp lên 10Gbps, 25Gbps hoặc 100Gbps, những giá trị mặc định này trở thành một rào cản lớn. Xử lý các gói tin 1,500-byte ở tốc độ 10Gbps buộc CPU phải xử lý hơn 800,000 ngắt (interrupt) mỗi giây. Điều này tạo ra kịch bản “cái chết bởi ngàn nhát cắt”, nơi bộ vi xử lý dành nhiều thời gian để quản lý tiêu đề (header) hơn là di chuyển dữ liệu thực tế, trừ khi sử dụng XDP eBPF trên Linux để xử lý gói tin ở tầng thấp.
Nếu bạn đang xây dựng các cụm lưu trữ Ceph, các nút NVMe-over-Fabrics lưu lượng cao hoặc các máy chủ ảo hóa, những tinh chỉnh này không phải là tùy chọn. Chúng là sự khác biệt giữa việc đạt được mức tối đa lý thuyết 9.41Gbps hoặc lãng phí hàng nghìn đô la vào phần cứng mà bạn không sử dụng hết công suất.
Tại sao các thiết lập mặc định thất bại ở tốc độ cao
Trước khi thay đổi cấu hình, bạn cần hiểu ba rào cản chính trong ngăn xếp mạng (networking stack) của Linux.
1. MTU và Jumbo Frames
Đơn vị truyền tải tối đa (MTU) quyết định kích thước gói tin lớn nhất được phép trên đường dây. Tiêu chuẩn MTU 1500-byte là tàn dư của Ethernet những năm 1980. Bằng cách tăng giá trị này lên 9000 bytes (Jumbo Frames), bạn cho phép hệ thống đóng gói lượng dữ liệu gấp sáu lần vào một gói tin duy nhất. Sự thay đổi đơn giản này giúp cắt giảm đáng kể số lượng ngắt CPU cần thiết để di chuyển cùng một lượng dữ liệu, tránh các lỗi ICMP Black Hole thường gặp khi thay đổi MTU.
2. TCP Window Scaling
TCP sử dụng một “cửa sổ” (window) để quyết định lượng dữ liệu có thể được gửi đi trước khi người gửi cần một thông báo xác nhận (ACK). Trên các liên kết có độ trễ cao hoặc băng thông lớn, một cửa sổ nhỏ sẽ khiến người gửi phải tạm dừng và chờ đợi. Điều này tạo ra vấn đề “đường ống dài và rộng” (long fat pipe), nơi băng thông luôn sẵn sàng nhưng giao thức lại từ chối sử dụng nó.
3. Ring Buffers và Ngắt (Interrupts)
Card mạng (NIC) của bạn có các hàng đợi nội bộ gọi là Ring Buffers. Nếu các bộ đệm này quá nhỏ, NIC sẽ loại bỏ các gói tin ngay cả trước khi CPU có cơ hội nhìn thấy chúng. Hơn nữa, cách NIC thông báo cho CPU—được gọi là Interrupt Coalescing—có thể được tinh chỉnh để ưu tiên thông lượng thô thay vì độ trễ micro-giây.
Bước 1: Triển khai Jumbo Frames (MTU 9000)
Thay đổi này mang lại hiệu suất tăng cao nhất, nhưng có một lưu ý quan trọng. Mọi thiết bị trên đường truyền dữ liệu phải hỗ trợ Jumbo Frames. Điều này bao gồm nguồn, đích và mọi switch ở giữa. Nếu một switch cũ ở giữa bị giới hạn ở mức 1500, các gói tin của bạn sẽ bị rớt hoặc bị phân mảnh, làm hỏng hiệu suất của bạn.
Để kiểm tra Jumbo Frames tức thì cho một giao diện như eth0:
sudo ip link set dev eth0 mtu 9000
Xác nhận thay đổi ngay lập tức với:
ip link show eth0
Để thay đổi vĩnh viễn trên Ubuntu hoặc Debian, hãy cập nhật tệp YAML Netplan của bạn trong /etc/netplan/:
network:
version: 2
ethernets:
eth0:
mtu: 9000
addresses:
- 10.0.0.10/24
Chạy sudo netplan apply để áp dụng MTU mới.
Bước 2: Tinh chỉnh ngăn xếp mạng Kernel (sysctl)
Kernel Linux cần các bộ đệm bộ nhớ lớn hơn để xử lý khối lượng dữ liệu khổng lồ trong luồng 10Gbps. Chúng ta cần mở rộng các bộ đệm này để hệ thống không bị nghẽn trong các đợt bùng nổ lưu lượng (bursts), bên cạnh việc làm chủ bảng Linux Conntrack để quản lý trạng thái kết nối.
Mở /etc/sysctl.conf và thêm các tham số này. Các giá trị này, đặc biệt là mức tối đa 32MB, đã được thử nghiệm thực tế để ổn định các liên kết 10G trong môi trường production:
# Tăng kích thước bộ đệm tối đa lên 32MB
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
# Kích thước bộ đệm TCP: [tối thiểu, mặc định, tối đa] tính bằng byte
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.tcp_wmem = 4096 65536 33554432
# Tăng độ dài của hàng đợi đầu vào bộ vi xử lý
net.core.netdev_max_backlog = 10000
# Đảm bảo TCP Window Scaling (RFC 1323) được kích hoạt
net.ipv4.tcp_window_scaling = 1
# Tăng giới hạn cho các kết nối đồng thời
net.core.somaxconn = 4096
Kích hoạt các thay đổi mà không cần khởi động lại:
sudo sysctl -p
Bước 3: Tối ưu hóa phần cứng NIC với ethtool
Nghẽn cổ chai cấp phần cứng thường ẩn náu trong cấu hình của chính NIC. Sử dụng tiện ích ethtool để xem liệu phần cứng có đang kìm hãm phần mềm hay không, một bước quan trọng trước khi tiến tới xử lý gói tin tốc độ cao với DPDK.
Tăng Ring Buffers
Kiểm tra khả năng phần cứng hiện tại của bạn:
ethtool -g eth0
Nếu “Current hardware settings” thấp hơn đáng kể so với “Pre-set maximums”, hãy tăng chúng lên. Đối với nhiều card Intel và Mellanox, điều này có nghĩa là chuyển từ 512 lên 4096:
sudo ethtool -G eth0 rx 4096 tx 4096
Interrupt Coalescing
Nếu mục tiêu của bạn là thông lượng tối đa cho các lần truyền tệp lớn, hãy yêu cầu NIC đợi 30 micro-giây trước khi ngắt CPU. Điều này cho phép nó gom nhóm các gói tin lại với nhau một cách hiệu quả:
sudo ethtool -C eth0 rx-usecs 30
Bước 4: Xác minh và Kiểm tra
Đừng bao giờ mặc định rằng cấu hình đã hoạt động chỉ vì lệnh không trả về lỗi. Hãy xác minh Jumbo Frames đang hoạt động thông suốt bằng lệnh ping với cờ “không phân mảnh” (DF):
ping -M do -s 8972 10.0.0.11
Lưu ý: Chúng ta sử dụng 8972 vì phần tải (payload) phải tính đến 28-byte tiêu đề ICMP và IP (9000 – 28 = 8972). Nếu lệnh ping phản hồi, đường truyền của bạn đã thông suốt.
Cuối cùng, hãy chạy một bài kiểm tra thông lượng thực tế bằng iperf3. Với MTU 9000 và kernel đã được tinh chỉnh, bạn sẽ thấy kết quả chạm mốc 9.4Gbps với mức sử dụng CPU thấp hơn đáng kể so với bài kiểm tra ban đầu. Bạn cũng có thể giám sát băng thông mạng dài hạn với vnStat để kiểm chứng sự ổn định.
Lời kết
Tối ưu hóa mạng 10Gbps không phải là về một cài đặt thần kỳ duy nhất. Đó là việc đảm bảo toàn bộ đường truyền—từ bộ nhớ kernel đến switch vật lý—đủ rộng cho dữ liệu. Nếu bạn không thể kiểm soát các switch của mình, hãy bỏ qua Jumbo Frames và tập trung hoàn toàn vào tinh chỉnh sysctl và ring buffer của NIC. Khi bạn cuối cùng đạt được tốc độ truyền tải duy trì 9.4Gbps, nỗ lực đó sẽ được đền đáp xứng đáng bằng sự ổn định và hiệu suất của hệ thống.

