Nghịch lý điểm nghẽn: Vì sao tốc độ đường truyền thực tế hiếm khi đạt mức lý thuyết
Bạn vừa thiết lập một đường truyền kết nối giữa các trung tâm dữ liệu lên tới 10 Gbps. Nhưng khi chạy đồng bộ bản sao PostgreSQL hoặc sao lưu dữ liệu offsite, tốc độ truyền tải lại bò lê lết ở mức 450 Mbps. Khi hiệu năng sụt giảm, bài ca đổ lỗi bắt đầu: nhà cung cấp đám mây khẳng định do ứng dụng của bạn, kỹ sư lưu trữ nghi ngờ switch top-of-rack, còn quản trị viên mạng khăng khăng bộ đếm giao diện không hề báo lỗi CRC nào.
Băng thông danh nghĩa chỉ đảm bảo tốc độ truyền tải trên dây ở tầng vật lý, không hơn không kém. Thông lượng thực tế phụ thuộc rất lớn vào giao thức truyền vận, độ trễ, số frame bị rớt và bộ đệm socket của kernel. Lệnh ping cơ bản chỉ đo được thời gian khứ hồi (RTT) nhưng lại hầu như không phát sinh lưu lượng. Trong khi đó, các công cụ như rsync hay scp lại chịu thêm gánh nặng từ I/O ổ đĩa, mã hóa SSH và giới hạn CPU đơn luồng. Những chi phí xử lý phụ trội này đã che khuất bản chất thực sự của vấn đề mạng.
Để tìm ra nguyên nhân gốc rễ, bạn cần bóc tách hoàn toàn lớp lưu trữ và tầng ứng dụng. Đây chính là lúc bài kiểm thử tải nhân tạo với iPerf3 phát huy sức mạnh.
Khái niệm cốt lõi: TCP Window, phân tích UDP và công thức BDP
Chạy kiểm thử một cách mù quáng sẽ chỉ cho ra những con số vô nghĩa. Để đọc vị kết quả chính xác, bạn cần nắm rõ cơ chế xử lý và phân phối gói tin của TCP cũng như UDP ở tầng dưới.
1. Tích số Băng thông – Độ trễ (Bandwidth-Delay Product – BDP)
TCP hoạt động dựa trên cơ chế cửa sổ trượt (sliding window). Bên gửi không thể truyền dữ liệu liên tục vô tận mà phải tạm dừng để chờ gói tin xác nhận (ACK) từ bên nhận. Lượng dữ liệu tối đa chưa được xác nhận có thể lưu chuyển trên đường truyền tại bất kỳ thời điểm nào được gọi là Tích số Băng thông – Độ trễ (BDP):
BDP = Băng thông (bits/giây) × Thời gian khứ hồi (giây)
Lấy ví dụ về kết nối AWS Transit Gateway giữa Frankfurt (eu-central-1) và Virginia (us-east-1). Bạn sở hữu đường truyền 1 Gbps với RTT là 80 ms:
BDP = 1.000.000.000 bps × 0,080 s = 80.000.000 bits = 10 Megabytes
Để khai thác tối đa đường truyền này, bên gửi cần duy trì liên tục 10 MB dữ liệu đang trên đường truyền (in-flight). Nếu bộ đệm cửa sổ nhận và gửi trên Linux (tcp_rmem và tcp_wmem) bị giới hạn ở mức mặc định là 2 MB, một luồng TCP đơn lẻ sẽ lập tức tắc nghẽn để chờ ACK ngay khi 2 MB rời khỏi socket. Điều này giới hạn thông lượng của luồng đơn ở mức xấp xỉ 200 Mbps (2 MB / 0,080 s), khiến 80% dung lượng đường truyền 1 Gbps hoàn toàn bị bỏ phí.
2. Kiểm soát nghẽn TCP so với đo tải Stress Test bằng UDP
TCP sẽ rơi vào trạng thái hoảng loạn khi bị rớt gói tin. Các thuật toán kiểm soát tắc nghẽn dựa trên mất gói như CUBIC mặc định coi mỗi frame bị mất là dấu hiệu của một router đang quá tải. Chúng ngay lập tức chém đôi cửa sổ tắc nghẽn (congestion window), kéo tụt toàn bộ thông lượng. Ngược lại, UDP bắn các gói tin vào đường truyền liên tục mà không cần chờ ACK hay tự hãm tốc độ. Bằng cách phát lưu lượng UDP với tốc độ bit không đổi, iPerf3 giúp bộc lộ hai chỉ số phần cứng cực kỳ quan trọng:
- Jitter (Độ lệch trễ): Sự biến thiên tính bằng mili-giây trong thời gian đến của các gói tin. Jitter cao sẽ phá hỏng các luồng âm thanh theo thời gian thực, truyền hình trực tiếp và tín hiệu heartbeat đồng thuận Raft.
- Datagram Loss (Tỷ lệ mất gói): Tỷ lệ phần trăm chính xác của các gói tin bị đánh rơi ở những mức tốc độ cụ thể (chẳng hạn như 250 Mbps, 500 Mbps hoặc 2 Gbps). Dấu hiệu này giúp phát hiện module quang thu phát bị lỗi, dây nhảy quang bị bẩn hoặc bộ đệm switch đã cạn kiệt.
Thực hành: Đo kiểm chuyên sâu và chẩn đoán điểm nghẽn
Bước 1: Cài đặt và thiết lập máy chủ cùng máy khách chuẩn
Cài đặt iPerf3 trên cả hai máy tham gia thử nghiệm:
# Trên Debian/Ubuntu
sudo apt update && sudo apt install -y iperf3
# Trên RHEL/AlmaLinux/Rocky
sudo dnf install -y iperf3
Khởi chạy server dưới dạng tiến trình nền daemon trên node nhận. Ràng buộc nó trực tiếp vào interface nội bộ để tránh lưu lượng bị định tuyến nhầm qua gateway công cộng:
# Bind vào IP nội bộ đích
iperf3 -s -B 10.10.20.15 -p 5201 -D
Hãy chắc chắn cổng 5201 đã được mở trên tường lửa (nftables, iptables hoặc security group) cho cả hai giao thức TCP và UDP trước khi chạy client.
Bước 2: So sánh TCP luồng đơn với bão hòa đa luồng
Từ máy client, thực hiện bài kiểm tra TCP kéo dài 20 giây với chu kỳ báo cáo 1 giây mỗi lần:
iperf3 -c 10.10.20.15 -t 20 -i 1
Quan sát kỹ hai cột: Retr (TCP retransmissions – số lần truyền lại) và Cwnd (kích thước cửa sổ tắc nghẽn). Số đếm Retr tăng dần đi kèm với Cwnd bị thu hẹp là tín hiệu rõ ràng cho thấy tình trạng mất gói đang diễn ra trên đường truyền.
Tiếp theo, thử nghiệm các luồng song song với tham số -P. Bài test đơn giản này sẽ chỉ ra tốc độ kém là do độ trễ hay do đường truyền vật lý đã bão hòa:
iperf3 -c 10.10.20.15 -t 20 -P 4
Nếu 1 luồng chỉ chạm trần ở mức 250 Mbps, nhưng 4 luồng song song đẩy thông lượng lên tới 980 Mbps trên cổng 1 Gbps, thì cáp vật lý và switch của bạn hoàn toàn bình thường. Nút thắt thực sự nằm ở giới hạn bộ đệm TCP trên các chặng mạng có độ trễ cao.
Bước 3: Chẩn đoán ngưỡng Jitter và mất gói bằng UDP
TCP thường che giấu việc mất gói vật lý bằng cơ chế tự động truyền lại. Hãy chuyển sang chế độ UDP (-u) để bóc trần những vị trí thiết bị trung gian đang đánh rơi frame. Bắt đầu đo ở mức thấp hơn nhiều so với tốc độ mạng dự kiến, sau đó tăng dần lên:
# Thăm dò độ ổn định của đường truyền ở mức 500 Mbps
iperf3 -c 10.10.20.15 -u -b 500M -t 15 -i 1
Quan sát bảng tổng kết khi phiên đo kết thúc:
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-15.00 sec 894 MBytes 500 Mbits/sec 0.041 ms 0/647820 (0%)
Nâng dần lưu lượng lên -b 800M, rồi -b 950M. Nếu tỷ lệ rớt gói vẫn giữ dưới 0.1% cho đến mức 820 Mbps rồi đột ngột tăng vọt qua 2.5%, bạn đã tìm thấy ngưỡng tới hạn chính xác. Đó là điểm mà bộ đệm ASIC của switch đã hoàn toàn cạn kiệt dung lượng dự phòng.
Bước 4: Kiểm tra tính bất đối xứng và lưu lượng hai chiều
Các tuyến đường mạng hiếm khi hoàn toàn đối xứng theo cả hai hướng. Các chính sách định tuyến bất đối xứng và đường truyền qua nhiều nhà cung cấp trung gian thường có hành vi khác nhau giữa chiều tải lên (uplink) và tải xuống (downlink). Bạn có thể kiểm tra chiều ngược lại mà không cần đổi máy thực hiện:
# Chế độ đảo chiều: Server phát, client nhận
iperf3 -c 10.10.20.15 -t 15 -R
# Kiểm tra đồng thời cả hai chiều
iperf3 -c 10.10.20.15 -t 15 --bidir
Nếu lưu lượng chiều đi đạt 940 Mbps nhưng chiều về bị nghẽn ở mức 120 Mbps, hãy kiểm tra lại bảng định tuyến. Rất có thể hệ thống đang gặp tình trạng lệch MTU, tuyến định tuyến bất đối xứng hoặc bộ định tuyến biên đang áp dụng chính sách traffic shaping quá gắt gao ở chiều ra.
Bước 5: Vượt qua giới hạn trần của bộ đệm
Khi các đường truyền trải dài trên khoảng cách địa lý lớn, bộ đệm socket mặc định của Linux sẽ kìm hãm thông lượng. Bạn có thể thử nghiệm các mức bộ đệm lớn hơn trực tiếp bằng cờ -w của iPerf3 trước khi can thiệp vào các tệp cấu hình hệ thống:
# Ép kích thước TCP window lên 8 Megabyte
iperf3 -c 10.10.20.15 -t 20 -w 8M
Nếu tốc độ truyền tải nhảy vọt từ 200 Mbps lên thẳng 920 Mbps, đích thị kernel đang là rào cản kìm chân bạn. Mở tệp /etc/sysctl.d/99-network-tuning.conf trên cả hai máy chủ và cập nhật lại các giới hạn bộ đệm:
# Tăng bộ nhớ socket nhận và gửi tối đa của hệ điều hành lên 32MB
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
# Cấu hình tự động tinh chỉnh TCP: min default max (tính bằng byte)
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.tcp_wmem = 4096 65536 33554432
# Kích hoạt thuật toán kiểm soát nghẽn BBR cùng cơ chế fair queuing
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Tải lại các tham số mới ngay lập tức mà không cần khởi động lại máy:
sudo sysctl --system
Cấu hình sysctl này thường xuyên giúp tăng gấp đôi tốc độ nhân bản trên các cụm Redis đa vùng và các bản sao đọc MySQL. Tuyệt vời nhất là nó giải quyết triệt để độ trễ mà không tốn kém thêm chi phí nâng cấp băng thông mạng.
Bước 6: Chẩn đoán socket trực tiếp trong quá trình kiểm thử
Trong lúc iPerf3 đang chạy ở một terminal, hãy mở terminal thứ hai để theo dõi trực tiếp các bộ đếm socket của kernel bằng lệnh ss:
ss -tin '( dport = :5201 or sport = :5201 )'
Lệnh này sẽ trích xuất số liệu thời gian thực trực tiếp từ kernel: RTT làm mượt (rtt), kích thước segment tối đa (mss), tốc độ phân nhịp (pacing rate) và bộ đếm truyền lại. Nếu interface của bạn sử dụng MTU chuẩn 1500 byte nhưng mss lại hiển thị 1360 thay vì 1460, chứng tỏ có một tunnel IPSec trung gian hoặc mạng overlay đám mây đang làm giảm kích thước gói tin. Hãy khắc phục lại Path MTU Discovery hoặc điều chỉnh TCP MSS clamping để tránh tình trạng phân mảnh gói tin.
Lời kết: Xây dựng quy trình chẩn đoán bài bản
Việc cô lập các sự cố suy giảm tốc độ mạng thực chất là một quy trình làm việc có hệ thống: Bắt đầu với một luồng TCP đơn. Đánh giá tổng dung lượng đường truyền bằng các luồng song song. Tiếp theo, cô lập các vị trí rớt gói bằng kiểm thử UDP có giới hạn tốc độ. Cuối cùng, tính toán Tích số Băng thông – Độ trễ và tinh chỉnh bộ đệm kernel sao cho tương thích.
Hãy chủ động đo kiểm chuẩn hóa mọi đường truyền liên trung tâm dữ liệu mới và ghi lại các con số cơ sở này. Sau này, khi ứng dụng bất ngờ chạy chậm lại sau sáu tháng hoạt động, bạn sẽ chỉ mất chưa đầy hai phút để xác định nguyên nhân bắt nguồn từ đường truyền mạng hay nằm ở mã nguồn ứng dụng.

