Server xử lý hàng nghìn request mỗi ngày nhưng người dùng vẫn phàn nàn tốc độ tải chậm? Đường truyền vật lý đủ năng lực, CPU và RAM không phải nút thắt — vấn đề thường nằm ở chỗ ít ai để ý: thuật toán điều khiển tắc nghẽn TCP mặc định của kernel.
Tại sao CUBIC lại là rào cản hiệu năng?
Linux mặc định dùng CUBIC — thuật toán congestion control có từ kernel 2.6.19 (năm 2006). Cách CUBIC hoạt động: tăng dần window size, khi gặp packet loss thì cắt giảm 50%, rồi tăng lại theo hàm cubic. Nghe có vẻ ổn, nhưng có hai vấn đề cốt lõi:
- CUBIC coi packet loss là dấu hiệu tắc nghẽn — trong khi loss thực tế có thể do nhiều nguyên nhân khác (đường truyền không ổn định, buffer overflow tạm thời)
- Trên kết nối có RTT cao — ví dụ server đặt ở Tokyo, user ở Hà Nội — CUBIC mất rất nhiều vòng lặp mới đạt được bandwidth tối đa. Sau mỗi lần giảm window, quá trình tăng lại rất chậm chạp
Trên con server chạy CentOS 7 cũ của công ty, mình đã phải tối ưu khá nhiều để đạt được performance mong muốn — và một trong những thay đổi có tác động rõ ràng nhất chính là chuyển sang TCP BBR. Khác biệt thể hiện ngay trên các kết nối xuyên quốc gia.
TCP BBR tiếp cận bài toán theo hướng khác
Google phát triển BBR (Bottleneck Bandwidth and Round-trip propagation time) năm 2016 và tích hợp vào Linux kernel 4.9. Thay vì phản ứng với packet loss, BBR mô hình hóa trực tiếp hai thông số vật lý của đường truyền:
- BtlBw (Bottleneck Bandwidth) — băng thông thực tế tại điểm nghẽn
- RTprop (Round-trip propagation time) — thời gian lan truyền tín hiệu thuần túy
BBR liên tục probe hai thông số này và điều chỉnh tốc độ gửi để đạt throughput tối đa mà không làm tràn buffer. Kết quả: băng thông sử dụng được tăng lên, latency giảm xuống, đặc biệt hiệu quả trên kết nối có RTT lớn hoặc có mất gói ngẫu nhiên.
CUBIC vs BBR — khác nhau ở cơ chế, không chỉ ở số liệu
- CUBIC: Tăng window → gặp loss → giảm 50% → tăng lại. Reactive, thích nghi chậm
- BBR: Probe bandwidth liên tục, tự điều chỉnh sending rate theo model toán học. Proactive, thích nghi nhanh với thay đổi điều kiện mạng
Google công bố BBR cải thiện throughput YouTube trung bình 4% toàn cầu và lên đến 14% trên các kết nối băng thông thấp. Ở scale hàng triệu kết nối đồng thời của Google, 4% không phải con số nhỏ.
Điều kiện để kích hoạt BBR
Trước khi bắt đầu, kiểm tra các yêu cầu sau:
- Kernel từ 4.9 trở lên (BBR được tích hợp từ phiên bản này)
- Quyền root hoặc sudo
- Ubuntu 18.04+, Debian 10+, CentOS 8+, AlmaLinux, Rocky Linux đều đáp ứng mặc định
CentOS 7 mặc định dùng kernel 3.10, không có BBR. Cần nâng cấp kernel qua ELRepo trước (yum install kernel-ml từ repo elrepo-kernel).
Kích hoạt TCP BBR từng bước
Bước 1: Kiểm tra trạng thái hiện tại
# Kiểm tra phiên bản kernel
uname -r
# Xem các thuật toán congestion control đang có sẵn
sysctl net.ipv4.tcp_available_congestion_control
# Xem thuật toán đang được dùng
sysctl net.ipv4.tcp_congestion_control
Output điển hình trên Ubuntu 22.04 (trước khi bật BBR):
$ uname -r
5.15.0-88-generic
$ sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = reno cubic
$ sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic
Bước 2: Load BBR module và cấu hình sysctl
# Load TCP BBR module vào kernel ngay lập tức
modprobe tcp_bbr
# Xác nhận module đã được load
lsmod | grep bbr
Tiếp theo, ghi cấu hình vào /etc/sysctl.conf để áp dụng vĩnh viễn:
cat >> /etc/sysctl.conf << 'EOF'
# TCP BBR congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF
Áp dụng ngay không cần reboot:
sysctl -p
Tại sao cần net.core.default_qdisc = fq? BBR hoạt động tốt nhất cùng với fq (Fair Queue) packet scheduler. FQ phân phối gói tin theo từng flow, tránh một connection chiếm hết queue, giảm jitter đáng kể so với pfifo_fast mặc định.
Để BBR module tự load sau mỗi lần khởi động:
echo "tcp_bbr" >> /etc/modules-load.d/modules.conf
Bước 3: Xác nhận BBR đang chạy
# Kiểm tra congestion control đang dùng
sysctl net.ipv4.tcp_congestion_control
# BBR phải xuất hiện trong danh sách available
sysctl net.ipv4.tcp_available_congestion_control
# Kiểm tra qdisc
sysctl net.core.default_qdisc
Output mong đợi:
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_available_congestion_control = reno cubic bbr
net.core.default_qdisc = fq
Tối ưu thêm với các tham số TCP liên quan
BBR một mình đã cải thiện rõ rệt. Nhưng kết hợp thêm vài tham số TCP liên quan, performance sẽ lên thêm một bậc. Thêm vào /etc/sysctl.conf:
cat >> /etc/sysctl.conf << 'EOF'
# Tăng buffer size cho high-throughput connections
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
# TCP Fast Open: gửi data ngay trong gói SYN, giảm 1 RTT
net.ipv4.tcp_fastopen = 3
# Tăng backlog cho server có nhiều concurrent connections
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# ECN hỗ trợ BBR phát hiện tắc nghẽn chính xác hơn
net.ipv4.tcp_ecn = 1
EOF
sysctl -p
TCP Fast Open (tcp_fastopen = 3) đặc biệt hữu ích cho web server: client gửi data trong gói SYN đầu tiên, tiết kiệm nguyên 1 RTT cho mỗi kết nối mới. Trên kết nối có RTT 80ms, điều này có nghĩa là trang web tải nhanh hơn hẳn 80ms.
Kiểm tra hiệu quả sau khi cấu hình
Dùng lệnh ss để quan sát các kết nối TCP đang hoạt động với BBR:
# Xem congestion control của từng TCP connection đang có
ss -tin | grep bbr
# Xem chi tiết một connection, bao gồm BBR stats
ss -tipm | grep -A 3 "ESTAB"
Để benchmark so sánh trước/sau, dùng iperf3:
# Cài iperf3
apt install iperf3 # Ubuntu/Debian
yum install iperf3 # CentOS/RHEL
# Chạy server mode trên VPS
iperf3 -s
# Chạy từ máy client ở địa điểm khác
# -t 30: test 30 giây, -P 4: 4 luồng song song
iperf3 -c YOUR_SERVER_IP -t 30 -P 4
Kết quả thực tế mình đo trên VPS Vultr Tokyo → client ở Hà Nội (RTT ~80ms): throughput tăng khoảng 25-30% so với CUBIC, jitter giảm rõ rệt. Kết quả sẽ khác nhau tùy điều kiện mạng, nhưng BBR gần như không bao giờ làm kết quả tệ hơn — worst case là tương đương CUBIC.
Một số lưu ý thực tế
- Kernel cũ hơn 4.9: Cần nâng cấp kernel trước. CentOS 7 dùng ELRepo, Ubuntu dùng
apt install linux-generic-hwe-* - BBR v2/v3: Google tiếp tục phát triển các phiên bản cải tiến nhưng chúng chưa được merge vào mainline kernel. Nếu dùng cloud kernel (GKE, AWS) hoặc distro có patch riêng, chạy
sysctl net.ipv4.tcp_available_congestion_controlsau khi update kernel để xem có available không - Môi trường container: Docker container dùng network namespace của host. BBR cần được bật ở host level, không thể cấu hình từ trong container
- Không cần reboot: Tất cả thay đổi sysctl áp dụng ngay lập tức. Chỉ cần reboot để module
tcp_bbrtự load quamodules-load.d
Kết luận
Bật BBR không phải việc lớn: vài lệnh sysctl, áp dụng ngay không cần reboot, roll back chỉ cần đổi lại tcp_congestion_control = cubic. Không chạm code ứng dụng, không thay phần cứng.
Tác động rõ nhất trên các kết nối cross-region — server Tokyo, user Hà Nội, hay bất kỳ cặp nào có RTT trên 50ms. Với mọi server production chạy kernel 4.9+, đây là tối ưu nên làm đầu tiên: worst case không có gì thay đổi, best case throughput tăng hàng chục phần trăm.

