Thin stream phục hồi chậm Thin streams fall back to RTO
ID nguyên nhân rt-thin · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)
Khi gửi gói nhỏ thưa thớt như game, RTO đến trước khi gom đủ “3 gói theo sau”. Với cùng mức mất gói, game đứng lâu hơn nhiều so với khi truyền dữ liệu dung lượng lớn.
Vì sao Khoảng cách giữa các gói khoảng 100 ms nên chỉ có vài gói chưa nhận được ACK (in-flight) → Dẫn đến Để gom đủ 3 ACK trùng phải mất hơn 300 ms nên RTO (ping + 200 ms) kích hoạt trước; mất liên tiếp thì mỗi lần tăng gấp đôi → Trên màn hình Mỗi lần mất gói đứng hình khoảng 0,3 giây; nếu mất cả gói đã gửi lại thì đứng gần 1 giây rồi tua nhanh
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Server: bật TCP_NODELAY (nếu Nagle còn bật thì RACK không có gói đi sau để dựa vào khi xác định mất gói), chuyển gói thời gian thực sang cơ chế truyền lại tự viết trên UDP. Client: bật TCP_NODELAY, gói thời gian thực dùng cùng cách với server (UDP).
Việc cần làm (Đội hạ tầng)
Dùng RACK-TLP (mặc định trên Linux mới), dùng tcp_thin_linear_timeouts để RTO liên tiếp không tăng gấp đôi.
Con số tham khảo
Với khoảng cách gói 100 ms và ping 60 ms, truyền lại nhanh mất khoảng 360 ms (đến khi 3 gói sau tới nơi và xác nhận quay về), còn RTO khoảng 260 ms. Nếu dùng RACK thì gửi lại ngay khi xác nhận của gói kế tiếp quay về, khoảng 160 ms. Khi khoảng cách gói vượt 200 ms thì RACK cũng không nhanh hơn RTO.
Trên đồ thị
Đứt quãng rồi dồn về · Lượng dữ liệu nhận theo từng kết nối, số lần RTO hết hạn
Chỗ cần xem
So sánh phần tăng của TcpExtTCPTimeouts (RTO hết hạn), TcpExtTCPFastRetrans (truyền lại nhanh), TcpExtTCPLossProbes và TcpExtTCPLossProbeRecovery (TLP) trong nstat; xem rto và backoff của kết nối game bằng ss -ti. Kiểm tra cả giá trị net.ipv4.tcp_recovery, tcp_early_retrans, tcp_sack của server
Đúng nếu
trong số lần truyền lại, RTO hết hạn nhiều hơn truyền lại nhanh, và thường thấy kết nối game có backoff lớn hơn 0 (đang chịu RTO). Lượng nhận bằng 0 trong lúc đứng, phục hồi xong thì dồn về một lượt
Loại trừ nếu
truyền dữ liệu dung lượng lớn trên cùng server cũng đứng lâu y như vậy → vấn đề mất gói không liên quan đến dạng kết nối. Tập trung ở kết nối thiếu SACK và timestamp → “Thiết bị trung gian xóa tùy chọn TCP”
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
Linux trước đây có tùy chọn dành cho thin stream để truyền lại ngay khi có 1 ACK trùng (tcp_thin_dupack), nhưng đã bị bỏ vào năm 2017, và hiện nay RACK đảm nhận vai trò đó. Nếu Nagle bật (TCP_NODELAY tắt), trong lúc chờ xác nhận cho gói bị mất, TCP cũng không gửi gói mới, nên RACK không có gói đi sau để dựa vào và phải chờ đến RTO.
Nguồn
Thin-streams and TCPLinux kernel Thin stream gửi thưa thớt như game không tận dụng được truyền lại nhanh nên phải trông vào timeout dài; tiêu chí là dưới 4 gói chưa nhận được ACK (in-flight)
RFC 8985: The RACK-TLP Loss Detection Algorithm for TCPIETF RACK xác định mất gói dựa trên việc gói gửi sau đã tới nơi; thời gian chờ TLP là 2·SRTT (nếu chỉ còn một gói chưa được xác nhận thì cộng thêm khoảng dự phòng cho delayed ACK)
include/net/tcp.hLinux kernel TCP_RTO_MIN 200 ms, tiêu chí thin stream (dưới 4 gói in-flight) và 6 lần thử lại tuyến tính
tcp: remove thin_dupack featureLinux kernel Giải thích việc thin_dupack bị xóa vào tháng 1 năm 2017 (Linux 4.11) và RACK đảm nhận vai trò đó
IP SysctlLinux kernel tcp_thin_linear_timeouts: với thin stream, không tăng gấp đôi RTO trong tối đa 6 lần (mặc định tắt)