← Về danh sách
Mạng
#TCP#혼잡제어#슬로우스타트#혼잡윈도우#CUBIC#130회
Cập nhật lần cuối · 2026-09-26

Kiểm soát tắc nghẽn TCP (Congestion Control)

1. Tổng quan

A. Định nghĩa

Cơ chế điều khiển đầu cuối của TCP tự điều chỉnh tốc độ gửi (cửa sổ tắc nghẽn) khi xảy ra tắc nghẽn (quá tải gói tin) bên trong mạng để giảm nhẹ·tránh tắc nghẽn. Nếu kiểm soát luồng (Flow Control) — điều chỉnh theo tốc độ xử lý của bộ đệm phía nhận — là 'bảo vệ bên nhận', thì kiểm soát tắc nghẽn nhằm mục đích 'bảo vệ tài nguyên dùng chung của mạng' như router·liên kết.

Lý do căn bản cần kiểm soát tắc nghẽn là 'ngăn chặn sụp đổ do tắc nghẽn (Congestion Collapse)'. Nếu nhiều bên gửi phớt lờ trạng thái mạng mà xả dữ liệu ồ ạt, hàng đợi đầu ra của router trung gian bị tràn và gói tin bị loại bỏ (tail drop). Khi đó bên gửi truyền lại các gói bị mất, và chính việc truyền lại này lại làm hàng đợi phình ra, gây thêm mất gói — một vòng luẩn quẩn. Rốt cuộc xảy ra sụp đổ trong đó liên kết đầy ắp lưu lượng truyền lại nhưng thông lượng hữu ích (goodput) lại tiến về 0. Thực tế, năm 1986 thời kỳ đầu Internet đã quan sát thấy sụp đổ do tắc nghẽn khiến thông lượng tức thời giảm hàng trăm lần, và nhân dịp đó Van Jacobson đưa vào thuật toán khởi động chậm·tránh tắc nghẽn — điểm xuất phát của kiểm soát tắc nghẽn TCP ngày nay.

Để giải quyết vấn đề này, TCP đưa ra một giả định khéo léo. Trong mạng có dây ít lỗi vô tuyến, mất gói được diễn giải chính là tín hiệu tắc nghẽn, và khi phát hiện mất gói thì tự nguyện giảm lượng gửi. Tức là tuân theo 'nguyên tắc đầu cuối (end-to-end principle)': giữ lõi mạng (router) đơn giản, đặt trí tuệ (logic điều khiển) ở đầu cuối (TCP của máy chủ). Nhờ các đầu cuối riêng lẻ hợp tác điều chỉnh tốc độ, tài nguyên dùng chung khổng lồ là Internet được duy trì ổn định mà không cần điều khiển trung tâm.

B. Sự cần thiết và phân biệt với kiểm soát luồng

Internet là tài nguyên được vô số đầu cuối cùng chia sẻ đồng thời, nên nếu mỗi bên chỉ khăng khăng tốc độ của mình thì toàn bộ sẽ sụp đổ. Kiểm soát tắc nghẽn là cơ chế cốt lõi để các đầu cuối tự chủ hợp tác, chia băng thông công bằng (fairness) và bảo vệ mạng khỏi sụp đổ. Ở đây việc phân biệt với kiểm soát luồng rất quan trọng. Kiểm soát luồng là bài toán 1:1, điều chỉnh bằng cửa sổ nhận (rwnd) để 'bên gửi nhanh không áp đảo bên nhận chậm', còn kiểm soát tắc nghẽn là bài toán nhiều:nhiều, điều chỉnh bằng cửa sổ tắc nghẽn (cwnd) để 'nhiều bên gửi không áp đảo mạng dùng chung'. Lượng gửi thực tế được quyết định bởi giá trị nhỏ hơn trong hai cửa sổ, bảo vệ đồng thời bên nhận và mạng.

Hai khái niệm thường bị nhầm lẫn nhưng khác nhau căn bản về đối tượng bảo vệ và nguồn tín hiệu. Tín hiệu của kiểm soát luồng là giá trị 'tường minh' rwnd mà bên nhận gửi kèm dung lượng bộ đệm còn trống, còn tín hiệu của kiểm soát tắc nghẽn thì mạng không cho biết nên phải suy luận từ các manh mối 'ngầm định' như mất gói·độ trễ. Vì khác biệt này, kiểm soát luồng tương đối mang tính tất định, còn kiểm soát tắc nghẽn mang tính xác suất, hiệu năng khác nhau nhiều tùy độ chính xác của suy luận.

Phân loại Kiểm soát luồng (Flow Control) Kiểm soát tắc nghẽn (Congestion Control)
Đối tượng bảo vệ Bộ đệm bên nhận (1:1) Tài nguyên dùng chung của mạng (nhiều:nhiều)
Biến điều khiển Cửa sổ nhận (rwnd) Cửa sổ tắc nghẽn (cwnd)
Tín hiệu Thông báo tường minh của bên nhận Suy luận ngầm từ mất gói·độ trễ·ECN
Lượng gửi thực tế min(cwnd, rwnd) thỏa mãn đồng thời hai ràng buộc

2. Các thành phần của cơ chế kiểm soát tắc nghẽn

flowchart LR
  A["Khởi động chậm<br/>(cwnd tăng theo hàm mũ)"] --> B["Tránh tắc nghẽn<br/>(cwnd tăng tuyến tính)"]
  B -->|"3 ACK trùng"| C["Truyền lại nhanh"]
  C --> D["Phục hồi nhanh<br/>(quay về tránh tắc nghẽn)"]
  D --> B
  B -->|"Hết thời gian (RTO)"| A
  style A fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px

Kiểm soát tắc nghẽn của TCP truyền thống (họ Reno) hoạt động với bốn thành phần ăn khớp như một máy trạng thái. Mỗi thành phần điều phối theo từng giai đoạn hai yêu cầu trái ngược: 'dò tìm băng thông mạnh bạo tới mức nào' và 'lùi lại bao nhiêu khi mất gói'.

Khởi động chậm (Slow Start) xuất phát khi đầu kết nối hoàn toàn không biết băng thông khả dụng. Bắt đầu cwnd từ 1 MSS và tăng gấp đôi theo hàm mũ mỗi RTT (1→2→4→8…) để dò băng thông nhanh chóng. Tên gọi là 'khởi động chậm' nhưng thực tế tốc độ tăng là hàm mũ nên rất mạnh bạo; chữ 'chậm' có nghĩa là 'xuất phát thận trọng từ 1'. Tăng theo hàm mũ dừng lại khi chạm ngưỡng (ssthresh) và chuyển sang tránh tắc nghẽn.

Tránh tắc nghẽn (Congestion Avoidance) cho rằng đã tiến gần giới hạn băng thông nên tăng cwnd tuyến tính 1 MSS mỗi RTT. Triết lý của giai đoạn này là 'AIMD (Additive Increase, Multiplicative Decrease)': bình thường thì cộng thêm từng chút để dò băng thông, khi mất gói thì giảm mạnh một nửa. Tính bất đối xứng 'tăng từ từ, giảm gấp' này là căn cứ lý thuyết tạo ra sự công bằng và ổn định giữa nhiều luồng.

Truyền lại nhanh (Fast Retransmit): khi nhận được 3 ACK trùng cùng số thứ tự, truyền lại ngay gói đó mà không chờ bộ định thời truyền lại (RTO) hết hạn. 3 ACK trùng là tín hiệu 'các gói sau đã tới, chỉ thiếu một gói', nên có thể phục hồi nhanh mà không cần chờ timeout đắt đỏ.

Phục hồi nhanh (Fast Recovery): ngay sau truyền lại nhanh, không đặt lại về khởi động chậm (cwnd=1) mà hạ ssthresh xuống một nửa giá trị hiện tại rồi quay về tránh tắc nghẽn tại điểm đó. Nó ngăn việc giảm tốc quá mức do bắt đầu lại từ đầu dù chỉ mất gói nhẹ, duy trì thông lượng trong tình huống mất gói cục bộ.

Thành phần Hoạt động Thay đổi cwnd
Khởi động chậm Dò băng thông ban đầu Tăng theo hàm mũ (×2 mỗi RTT), tới ssthresh
Tránh tắc nghẽn Tăng băng thông thận trọng (AIMD) Tăng tuyến tính (+1 MSS mỗi RTT)
Truyền lại nhanh Truyền lại ngay khi có 3 ACK trùng (kích hoạt truyền lại)
Phục hồi nhanh Sau truyền lại thì quay về tránh tắc nghẽn ssthresh=cwnd/2 rồi quay lại tại điểm đó

3. Tín hiệu phát hiện tình trạng tắc nghẽn

Cửa sổ để TCP 'nhìn thấy' tắc nghẽn không phải phép đo tường minh mà là tín hiệu gián tiếp. Vì không thể nhìn trực tiếp vào bên trong router, TCP suy luận trạng thái mạng từ dạng thức ACK đến. Độ chính xác của suy luận này quyết định chất lượng kiểm soát tắc nghẽn.

Hết thời gian chờ (RTO) là tình huống hoàn toàn không có ACK trong một khoảng thời gian nhất định, nghĩa là nhiều gói liên tiếp đã biến mất. Điều này được diễn giải là tín hiệu tắc nghẽn nghiêm trọng (hoặc đứt đường), TCP hạ ssthresh xuống một nửa, đặt lại cwnd về 1 rồi bắt đầu lại từ khởi động chậm. Đây là phản ứng lùi mạnh nhất.

3 ACK trùng là tình huống nhẹ khi chỉ một số gói bị mất. Vì các gói sau đã tới nên cho rằng mạng không bị nghẽn hoàn toàn, và phản ứng mềm mại bằng truyền lại nhanh·phục hồi nhanh chỉ giảm cwnd một nửa. Sự tinh tế của TCP là dù cùng là 'mất gói' nhưng mức độ lùi khác nhau tùy loại tín hiệu.

ECN (Explicit Congestion Notification, thông báo tắc nghẽn tường minh) là cách router đặt bit trong header IP trước khi xảy ra mất gói để báo trước 'sắp tắc nghẽn'. Thay vì báo tắc nghẽn bằng cách loại bỏ gói thì báo bằng thông báo, nên giảm được truyền lại và độ trễ, và đang được mở rộng sử dụng trong trung tâm dữ liệu·mạng di động hiện đại.

Tín hiệu Ý nghĩa Phản ứng (cwnd)
Hết thời gian chờ (RTO) Mất nhiều gói, tắc nghẽn nghiêm trọng cwnd=1, khởi động chậm lại
3 ACK trùng Mất một gói, nhẹ Truyền lại·phục hồi nhanh (cwnd một nửa)
Đánh dấu ECN Router báo trước khi mất gói Giảm tốc chủ động không mất gói

4. Cửa sổ tắc nghẽn (cwnd), hành vi răng cưa và sự tiến hóa của thuật toán

Biến trạng thái cốt lõi cửa sổ tắc nghẽn (cwnd) biểu thị lượng dữ liệu có thể đẩy vào mạng khi chưa được xác nhận bằng ACK, tức tốc độ gửi tức thời. Như đã nói, lượng có thể gửi thực tế được quyết định bởi min(cwnd, rwnd). Khi phát hiện tắc nghẽn, ssthresh được hạ xuống một nửa cwnd hiện tại, cwnd giảm, rồi lại tăng dần. Dạng sóng răng cưa (sawtooth) vẽ ra do lặp lại 'tăng tuyến tính → giảm một nửa khi mất gói → tăng lại' này là đặc trưng biểu tượng của kiểm soát tắc nghẽn TCP truyền thống. Chiều cao trung bình của răng cưa chính là thông lượng trung bình, nên mất gói càng thường xuyên (răng cưa bị gọt càng nhiều) thì thông lượng càng thấp.

Mô hình răng cưa dựa trên mất gói này bộc lộ giới hạn trên 'đường ống dài và mập (long fat pipe)' có băng thông lớn và độ trễ dài. Ví dụ trên liên kết tốc độ cao liên lục địa, một lần mất gói làm cwnd giảm một nửa thì phải mất hàng trăm RTT (vài giây trở lên) để phục hồi cửa sổ ban đầu bằng tăng tuyến tính, không lấp đầy được liên kết. Các thuật toán đã tiến hóa để giải quyết vấn đề này.

Tahoe là dạng đầu tiên, khi mất gói luôn quay về khởi động chậm. Reno đưa vào phục hồi nhanh để giảm sự tụt dốc khi mất gói cục bộ. CUBIC, mặc định của Linux ngày nay, tăng cửa sổ theo hàm bậc ba (cubic) của thời gian, phục hồi nhanh tới gần điểm cũ sau khi giảm một nửa nhưng dò thận trọng quanh đó, nâng mạnh mức sử dụng trong môi trường băng thông cao·độ trễ cao. BBR (Bottleneck Bandwidth and RTT) do Google phát triển thì thay đổi hẳn cách tiếp cận, không chờ mất gói mà trực tiếp ước lượng băng thông nút cổ chai và RTT nhỏ nhất để tính tốc độ gửi tối ưu. Nó đặc biệt hiệu quả trong môi trường vô tuyến·bufferbloat nơi dễ hiểu nhầm mất gói là tín hiệu tắc nghẽn, và đã được áp dụng cho các dịch vụ quy mô lớn như YouTube.

Thuật toán Ý tưởng cốt lõi Đặc điểm·áp dụng
Tahoe Quay về khởi động chậm khi mất gói Dạng đầu tiên, phục hồi chậm
Reno Đưa vào truyền lại nhanh·phục hồi nhanh Cải thiện ứng phó mất gói cục bộ
CUBIC Tăng cửa sổ dựa trên hàm bậc ba Tối ưu cho băng thông cao·độ trễ cao (mặc định Linux)
BBR Ước lượng trực tiếp băng thông·RTT (dựa trên mô hình) Mạnh trong vô tuyến·bufferbloat (Google)

5. Nâng cao: Kiểm soát tắc nghẽn trong thời đại trung tâm dữ liệu·di động

flowchart TB
  subgraph Sender["Máy trạng thái TCP của máy gửi"]
    direction LR
    SS["Khởi động chậm"] -->|"cwnd ≥ ssthresh"| CA["Tránh tắc nghẽn"]
    CA -->|"3 dup ACK"| FR["Truyền lại/phục hồi nhanh"]
    FR --> CA
    CA -->|"RTO"| SS
    SS -->|"RTO"| SS
  end
  Router["Router<br/>(đánh dấu ECN / AQM)"] -.Tín hiệu tắc nghẽn.-> Sender
  style SS fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px

Điều khiển dựa trên mất gói truyền thống bất lợi về độ trễ (latency) ở chỗ 'chờ cho tới khi bộ đệm đầy và gói bị loại bỏ'. Nếu router đặt bộ đệm quá lớn thì không mất gói nhưng độ trễ xếp hàng tăng — hiện tượng bufferbloat — làm giảm khả năng phản hồi của các dịch vụ thời gian thực như hội nghị truyền hình·game. Vì thế xu hướng gần đây đang chuyển sang hướng 'phản ứng trước bằng tín hiệu độ trễ, trước khi mất gói'.

Trục thứ nhất là kết hợp quản lý hàng đợi chủ động (AQM) với ECN. Khi router dùng các thuật toán như CoDel·PIE thấy dấu hiệu hàng đợi phình ra, thay vì loại gói thì đặt bit ECN để yêu cầu bên gửi giảm tốc trước. Phiên bản tinh chỉnh dành riêng cho trung tâm dữ liệu là DCTCP, giảm cửa sổ một cách tinh tế tỷ lệ với tỷ lệ gói bị đánh dấu ECN, đạt đồng thời độ trễ cực thấp và mức sử dụng cao.

Trục thứ hai là sự lan rộng của điều khiển dựa trên mô hình. Cách tiếp cận tiêu biểu là BBR, thay vì lấy mất gói làm tín hiệu thì trực tiếp ước lượng đặc tính vật lý của liên kết (băng thông·RTT), nên giảm được vấn đề hiểu nhầm mất gói không do tắc nghẽn của liên kết vô tuyến là tắc nghẽn rồi giảm tốc không cần thiết. Thứ ba, còn có xu hướng bản thân tầng giao vận tiến hóa. QUIC (nền tảng của HTTP/3) hiện thực kiểm soát tắc nghẽn trong không gian người dùng trên UDP, cho phép thử nghiệm·triển khai nhanh các thuật toán như CUBIC·BBR mà không cần thay kernel, đồng thời tích hợp kết nối·mã hóa·kiểm soát tắc nghẽn để giảm độ trễ ban đầu. Điều này cho thấy kiểm soát tắc nghẽn đã bước vào thời đại không còn bị giam trong TCP của kernel mà tiến hóa linh hoạt ở tầng ứng dụng.

6. Các lưu ý và hàm ý

  1. Chuyển dịch mô hình từ dựa trên mất gói sang dựa trên mô hình·độ trễ. Reno·CUBIC lấy mất gói làm tín hiệu tắc nghẽn, nhưng điều này gây phán đoán sai trong môi trường vô tuyến·băng thông cao. Các cách như BBR·DCTCP trực tiếp tận dụng băng thông·độ trễ·ECN đạt đồng thời độ trễ cực thấp và mức sử dụng cao, nên con mắt chọn mô hình tín hiệu phù hợp theo môi trường là quan trọng.

  2. Tinh chỉnh thuật toán phù hợp đặc tính mạng. Độ trễ thấp·băng thông cao của trung tâm dữ liệu, độ trễ cao·mất gói cao của vệ tinh·di động, và Internet thông thường có thuật toán tối ưu khác nhau. Trên Linux có thể chọn CUBIC·BBR, v.v. qua net.ipv4.tcp_congestion_control, nên phải điều chỉnh dựa trên đo lường thực tế phù hợp với đặc tính lưu lượng của dịch vụ (truyền khối lượng lớn dài hạn vs yêu cầu/phản hồi ngắn).

  3. Ứng phó bufferbloat và đánh đổi độ trễ-thông lượng. Nếu chỉ chạy theo thông lượng mà đặt bộ đệm lớn thì độ trễ xấu đi. Cần áp dụng đồng thời AQM (CoDel/PIE) và ECN để dẫn dắt giảm tốc trước khi mất gói, thiết kế cân bằng giữa tính thời gian thực và mức sử dụng băng thông. Đặc biệt với dịch vụ hội nghị truyền hình·cloud gaming, độ trễ chính là chất lượng.

  4. Công bằng (fairness) và vấn đề lẫn lộn thuật toán. Khi các thuật toán kiểm soát tắc nghẽn khác nhau cùng chia sẻ một nút cổ chai, băng thông có thể bị chia không công bằng (ví dụ thuật toán hung hăng xâm chiếm băng thông của thuật toán thụ động). Khi vận hành hạ tầng quy mô lớn, phải chuẩn hóa·kiểm chứng có tính đến cả khả năng bất công·bất ổn do lẫn lộn thuật toán.

  5. Linh hoạt hóa tầng giao vận và triển vọng tương lai. Chuyển kiểm soát tắc nghẽn sang không gian người dùng như QUIC/HTTP/3 cho phép cải tiến·thử nghiệm nhanh mà không bị ràng buộc bởi chu kỳ phát hành kernel. Tương lai dự báo kiểm soát tắc nghẽn dựa trên học máy (học tăng cường) hay điều khiển thích ứng theo yêu cầu ứng dụng (nhạy độ trễ/nhạy thông lượng) sẽ lan rộng, nên từ góc nhìn Kỹ sư chuyên nghiệp cần tầm nhìn coi đó là 'tầng giao vận đang tiến hóa' chứ không phải 'TCP cố định'.

Tài liệu tham khảo


Tóm tắt một câu: Kiểm soát tắc nghẽn TCP điều chỉnh cửa sổ tắc nghẽn (cwnd) theo dạng răng cưa AIMD bằng khởi động chậm·tránh tắc nghẽn·truyền lại nhanh·phục hồi nhanh và phát hiện tắc nghẽn qua timeout·ACK trùng·ECN để ngăn sụp đổ do tắc nghẽn, đồng thời đang tiến hóa từ dựa trên mất gói (Reno·CUBIC) sang dựa trên mô hình·độ trễ (BBR·DCTCP) và QUIC.