한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › ต้นเหตุของการส่งซ้ำใน TCP

การส่งซ้ำโดยไม่จำเป็นเพราะความหน่วงพุ่ง Spurious RTO from delay spikes

ID สาเหตุ rt-spurious-delay · ผู้รับผิดชอบหลัก ภายนอก (ภายนอก) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา), พัฒนาไคลเอนต์ (ทีมพัฒนาเกม)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

แพ็กเก็ตยังอยู่ครบและแค่มาถึงช้ามากชั่วครู่ แต่ถ้าความหน่วงนั้นนานกว่า RTO ฝั่งส่งจะตัดสินว่าหายแล้วส่งซ้ำ

ทำไม bufferbloat, โหมดประหยัดพลังงานของ Wi-Fi, การเปลี่ยนสถานะวิทยุของมือถือ หรือ VM ถูกพักการทำงาน ทำให้ความหน่วงพุ่งชั่วขณะหลายร้อย ms → ผลคือ RTO หมดเวลาก่อนจึงส่งซ้ำ แล้วแพ็กเก็ตต้นฉบับก็มาถึงตามมา (ฝั่งรับได้รับซ้ำ) → บนหน้าจอ อาการค้างและกรอเร็วมาจากความหน่วงพุ่งเอง การส่งซ้ำโดยไม่จำเป็นแทบไม่ทำให้ค้างนานขึ้น แค่ดันเมตริกการส่งซ้ำให้สูงจนถูกเข้าใจผิดว่าแพ็กเก็ตหาย

อาการ
ค้าง, กรอเร็ว, อินพุตดีเลย์
ปัจจัย
ความหน่วง, จิตเตอร์
ใครเจอ
เราคนเดียว, ทั้งเซิร์ฟเวอร์
เกิดเมื่อไร
สุ่มเป็นครั้งคราว, หลังอยู่เฉย ๆ สักพัก
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก ภายนอก (ภายนอก) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา), พัฒนาไคลเอนต์ (ทีมพัฒนาเกม)
งานฝั่งทีมพัฒนาเกม
ไคลเอนต์ Android 10 ขึ้นไปให้ขอโหมด Wi-Fi ความหน่วงต่ำระหว่างเล่น (Wi-Fi lock แบบ WIFI_MODE_FULL_LOW_LATENCY มีผลเฉพาะเมื่อจอเปิดอยู่และเกมอยู่เบื้องหน้า) เพื่อลดความหน่วงพุ่งจากโหมดประหยัดพลังงาน
งานฝั่งทีมอินฟรา
หลีกเลี่ยงอินสแตนซ์แบบ burstable, อย่าลดค่าต่ำสุดของ RTO ต่ำเกินไป, คง F-RTO และ timestamps ไว้ (tcp_frto, tcp_timestamps), ดูเมตริกการส่งซ้ำคู่กับ TCPSpuriousRTOs และ TCPDSACKRecv ของ nstat เพื่อไม่ให้เข้าใจผิดว่าแพ็กเก็ตหาย
งานฝั่งภายนอก
แนะนำให้ผู้เล่นใช้ SQM บนเราเตอร์และปิดโหมดประหยัดพลังงานของ Wi-Fi เพื่อลดความหน่วงพุ่งที่ต้นเหตุ
ตัวเลขที่ควรรู้
Linux ตรวจจับ RTO ที่ไม่จำเป็นด้วย F-RTO และบางครั้งก็ย้อนการลดอัตราการส่งกลับคืน ตรวจได้จาก TCPSpuriousRTOs (จำนวนครั้งที่ตัดสินว่าเป็น RTO ที่ไม่จำเป็น) และ TCPDSACKRecv (จำนวนครั้งที่ฝั่งรับแจ้งว่า “ได้รับไปแล้ว”) ใน nstat
บนกราฟ
พุ่งแบบสุ่มเป็นครั้งคราว · RTT (ปิง), จำนวน RTO ที่ไม่จำเป็น
จุดที่ต้องดู
ค่าที่เพิ่มขึ้นของ TcpExtTCPTimeouts (RTO หมดเวลา), TcpExtTCPSpuriousRTOs, TcpExtTCPDSACKRecv และ TcpExtTCPLostRetransmit จากการรัน nstat ทุก 1 นาที ดูไปพร้อมกัน ถ้ามี packet capture ใช้ตัวกรอง Wireshark tcp.analysis.spurious_retransmission
สัญญาณว่าใช่
เมื่อ RTO เพิ่ม TcpExtTCPSpuriousRTOs หรือ TcpExtTCPDSACKRecv ก็เพิ่มตาม และในเวลาเดียวกัน RTT พุ่งเป็นหลายร้อย ms ใน capture ฝั่งรับมีทั้งแพ็กเก็ตต้นฉบับและแพ็กเก็ตที่ส่งซ้ำมาถึง
สัญญาณว่าไม่ใช่
TcpExtTCPSpuriousRTOs และ DSACK ไม่ขยับ แต่ TcpExtTCPLostRetransmit (แพ็กเก็ตที่ส่งซ้ำก็หายอีก) เพิ่มขึ้น: เป็นแพ็กเก็ตหายจริง ถ้า RTT ไม่พุ่งแต่ DSACK สูงอยู่ตลอด น่าจะเป็น “fast retransmit โดยไม่จำเป็นเพราะแพ็กเก็ตสลับลำดับ”
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)

แหล่งอ้างอิง

  1. RFC 5682: Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP IETF
    F-RTO: ใช้ ACK ที่มาหลัง RTO แยกแยะว่าเป็น RTO ที่ไม่จำเป็นหรือไม่
  2. RFC 3481: TCP over Second (2.5G) and Third (3G) Generation Wireless Networks IETF
    ความหน่วงพุ่งในเครือข่ายมือถือ (เช่น handover และการกู้คืนลิงก์) ทำให้เกิด TCP timeout และการส่งซ้ำที่ไม่จำเป็น รวมถึงการลด congestion window
  3. RFC 2883: An Extension to the Selective Acknowledgement (SACK) Option for TCP IETF
    DSACK: ฝั่งรับแจ้งว่าได้รับซ้ำ ฝั่งส่งจึงรู้ว่ามีการส่งซ้ำโดยไม่จำเป็น
  4. SNMP counter Linux kernel
    TcpExtTCPSpuriousRTOs (RTO ที่ไม่จำเป็นซึ่ง F-RTO ตรวจพบ), TcpExtTCPDSACKRecv (จำนวน DSACK ที่ได้รับ), TcpExtTCPLostRetransmit (จำนวนครั้งที่ SACK แจ้งว่าแพ็กเก็ตที่ส่งซ้ำหายอีก)
  5. IP Sysctl Linux kernel
    tcp_frto เปิดเป็นค่าเริ่มต้น (เป็นผลดีกับเครือข่ายไร้สายที่ RTT แกว่ง), tcp_timestamps ค่าเริ่มต้น 1
  6. RFC 6298: Computing TCP's Retransmission Timer IETF
    หลักฐานว่าต้องใช้ค่าต่ำสุดของ RTO ที่สูงพอเพื่อกันการส่งซ้ำโดยไม่จำเป็น (แนะนำอย่างน้อย 1 วินาที)
  7. WifiManager Android (Google)
    WIFI_MODE_FULL_LOW_LATENCY (API 29, Android 10): Wi-Fi lock แบบความหน่วงต่ำที่มีผลเฉพาะเมื่อเชื่อมต่อ AP อยู่ จอเปิดอยู่ และแอปอยู่เบื้องหน้า
  8. net/ipv4/proc.c Linux kernel
    ชื่อตัวนับที่ nstat แสดง: TCPTimeouts, TCPSpuriousRTOs, TCPDSACKRecv, TCPLostRetransmit
  9. net/ipv4/tcp_timer.c Linux kernel
    TCPTimeouts เพิ่มขึ้นเมื่อตัวจับเวลาส่งซ้ำ (RTO) หมดเวลา
  10. nstat(8) — Linux manual page iproute2
    โดยค่าเริ่มต้น nstat แสดงค่าที่เพิ่มขึ้นนับจากการรันครั้งก่อน
  11. Display Filter Reference: Transmission Control Protocol Wireshark
    display filter tcp.analysis.spurious_retransmission

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: ต้นเหตุของการส่งซ้ำใน TCP

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง