Tối ưu độ trễ và xử lý triệt để Bufferbloat trên Linux bằng CAKE và FQ-CoDel

Network tutorial - IT technology blog
Network tutorial - IT technology blog

So sánh các giải pháp xử lý Bufferbloat trên Linux

Đang gõ SSH mượt mà thì đồng nghiệp kéo torrent hoặc backup 50GB lên cloud, ping nhảy vọt từ 15ms lên tận 450ms. Đó là triệu chứng kinh điển của Bufferbloat. Thiết bị mạng cố tình đệm quá nhiều gói để hạn chế rớt gói TCP. Hậu quả là hàng đợi phình to. Các gói tin cần độ trễ thấp như DNS lookup, SSH keystroke hay cuộc gọi VoIP bị kẹt cứng phía sau.

Linux cung cấp ba cơ chế hàng đợi (qdisc) phổ biến để giải quyết bài toán này:

  • Default FIFO (pfifo_fast): Hàng đợi vào trước – ra trước cổ điển. Gói nào đến trước đi trước. Khi một luồng bão hòa băng thông, buffer đầy ứ khiến mọi kết nối khác đều lag.
  • FQ-CoDel (Fair Queuing Controlled Delay): Chia lưu lượng thành 1024 hàng đợi con riêng biệt. Thuật toán CoDel tự động drop hoặc gắn cờ ECN khi hàng đợi bắt đầu ứ đọng. FQ-CoDel đã có sẵn trong Linux kernel từ bản 3.5.
  • CAKE (Common Applications Kept Enhanced): Bản nâng cấp toàn diện của FQ-CoDel dành cho router biên. CAKE gộp sẵn shaper băng thông, tự bù trừ overhead ở tầng vật lý (PPPoE, Ethernet framing) và phân bổ lưu lượng công bằng theo từng host.

Phân tích ưu nhược điểm kỹ thuật: FQ-CoDel vs CAKE

Mỗi thuật toán giải quyết nút thắt ở một vị trí khác nhau trong hạ tầng mạng:

1. FQ-CoDel

Ưu điểm:

  • Tiêu tốn cực ít CPU, chạy mượt trên cả VPS 1 vCPU lẫn switch Linux chịu tải hàng chục Gbps.
  • Không đòi hỏi căn chỉnh tham số rườm rà. Thuật toán tự thích nghi theo RTT mạng thực tế.
  • Sẵn sàng hoạt động ngay trên mọi bản phân phối Linux mà không cần cài module ngoài.

Nhược điểm:

  • Không tích hợp sẵn traffic shaper. Muốn bóp băng thông cổng WAN để ép buffer hình thành trên Linux, bạn phải ghép FQ-CoDel với HTB qua cú pháp tc rất dài dòng.
  • Chỉ chia đều theo 5-tuple (IP/Port nguồn – đích và protocol). Một máy tải đa luồng mở 40 kết nối vẫn lấn át máy chỉ mở 1 phiên làm việc.

2. CAKE (qdisc_cake)

Ưu điểm:

  • Tích hợp sẵn shaper băng thông cực kỳ ổn định. Bạn chỉ cần khai báo một dòng lệnh thay vì dựng cây HTB phức tạp.
  • Hỗ trợ chế độ triple-isolate: chia đều băng thông theo từng host thay vì từng luồng. Một IP không thể bóp nghẹt toàn mạng văn phòng.
  • Tự tính toán bù trừ overhead tầng vật lý (như FTTH PPPoE, VLAN, DOCSIS). Gói tin không bị dồn ứ bất ngờ tại modem nhà mạng.
  • Tự nhận diện và ưu tiên gói theo trường DiffServ (DSCP) mà không cần cấu hình iptables/nftables thủ công.

Nhược điểm:

  • Ăn CPU hơn FQ-CoDel khoảng 15-25% do phải tính toán overhead và hash nhiều tầng.
  • Yêu cầu kernel Linux 4.19 trở lên (Ubuntu 20.04+, Debian 10+ đều đã hỗ trợ sẵn).

Kinh nghiệm chọn giải pháp cho từng mô hình

Không nên mặc định dùng CAKE cho mọi trường hợp:

  • Chọn FQ-CoDel cho: Máy chủ dịch vụ độc lập, cụm Kubernetes, hoặc cổng nội bộ 10Gbps/40Gbps. Tại đây cổ chai không nằm ở interface của máy. FQ-CoDel giữ độ trễ siêu thấp với chi phí tính toán gần như bằng không.
  • Chọn CAKE cho: Router biên, Linux Gateway văn phòng hoặc homelab quay PPPoE ra Internet. Khi đường truyền 200Mbps cắm vào cổng NIC 1Gbps, CAKE phát huy tối đa nhờ shaper tích hợp để giành quyền kiểm soát hàng đợi về tay Linux.

Hướng dẫn cấu hình thực tế trên Linux

Bước 1: Kiểm tra qdisc hiện tại và đo đạc Bufferbloat

Đầu tiên, kiểm tra xem card mạng chính đang chạy cơ chế hàng đợi nào:

# Xem queue discipline trên interface eth0
tc qdisc show dev eth0

Nếu terminal trả về pfifo_fast hoặc mq đơn thuần, hệ thống chưa bật thuật toán quản lý hàng đợi chủ động.

Bạn có thể kiểm tra nhanh độ trễ bằng cách mở 2 cửa sổ terminal: một bên ping 1.1.1.1, một bên kéo file lớn bằng curl -O hoặc chạy iperf3. Nếu ping vọt từ 20ms lên 200-300ms, mạng của bạn dính Bufferbloat nặng.

Bước 2: Kích hoạt FQ-CoDel cho máy chủ Stand-alone

Với web server, database node hoặc VM thông thường, bạn chỉ cần gán FQ-CoDel vào card mạng:

# Đổi qdisc mặc định sang fq_codel trên eth0
sudo tc qdisc replace dev eth0 root fq_codel

# Xem trạng thái và thông số thống kê gói
tc -s qdisc show dev eth0

Bảng kết quả sẽ hiển thị số gói drops, ecn_mark và số lượng flow hoạt động. FQ-CoDel tự dàn xếp lưu lượng để không flow nào bị chiếm dụng hàng đợi quá lâu.

Bước 3: Cấu hình CAKE trên Linux Router / Gateway

Nguyên tắc vàng khi chống nghẽn: đặt shaper ở mức 90% đến 95% tốc độ thực tế của đường truyền. Nhờ đó, hàng đợi luôn tích tụ tại Linux thay vì tràn sang modem ISP.

Trước khi chia rule cho từng dải mạng nội bộ, bạn có thể tra cứu nhanh network range và số host bằng toolcraft.app/vi/tools/developer/ip-subnet-calculator để tránh nhầm subnet mask.

Giả sử cổng WAN ra Internet là eth0 và đường truyền gói 100Mbps (thực tế đo được 95Mbps ổn định):

# Thiết lập CAKE shaper ở mức 90Mbps, bù trừ overhead Ethernet, chia đều theo host:
sudo tc qdisc replace dev eth0 root cake bandwidth 90mbit ethernet triple-isolate nonat

# Nếu interface này trực tiếp thực hiện NAT ra ngoài, bật cờ nat để CAKE theo dõi conntrack:
sudo tc qdisc replace dev eth0 root cake bandwidth 90mbit ethernet nat dual-srchost

Quan sát trạng thái hoạt động ngay sau khi áp dụng:

tc -s qdisc show dev eth0

Output hiển thị rõ target delay (thường ở mức 5ms), dung lượng buffer đã dùng, số gói bị drop và tỷ lệ đánh dấu ECN.

Bước 4: Lưu cấu hình tự động chạy sau khi Reboot

Các lệnh tc sẽ biến mất khi restart máy. Để duy trì rule lâu dài, giải pháp sạch nhất là tạo một systemd service.

Mở file /etc/systemd/system/cake-sqm.service:

sudo nano /etc/systemd/system/cake-sqm.service

Điền nội dung sau (nhớ thay đúng interface và mức bandwidth của bạn):

[Unit]
Description=Apply CAKE SQM to eth0
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/sbin/tc qdisc replace dev eth0 root cake bandwidth 90mbit ethernet nat dual-srchost
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Kích hoạt service:

sudo systemctl daemon-reload
sudo systemctl enable --now cake-sqm.service

Bây giờ bạn có thể thử stress test lại đường truyền. Ngay cả khi tải tối đa 100% băng thông, ping chỉ lệch từ 1ms đến 5ms so với trạng thái mạng rảnh.

Share: