คู่มือเกมแลค › ต้นเหตุของการส่งซ้ำใน TCP
ค่า RTO ไม่เหมาะกับสภาพแวดล้อม RTO min too low or too high
ID สาเหตุ rt-rto-setting · ผู้รับผิดชอบหลัก อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าลดค่าต่ำสุดของ RTO มากเกินไป แค่ช้านิดเดียวก็เกิดการส่งซ้ำโดยไม่จำเป็น ส่วนค่าเริ่มต้น (200 ms) ก็นานเกินไปสำหรับเกม ทุกครั้งที่แพ็กเก็ตหายจึงหยุดนาน
ทำไม ลดค่าต่ำสุดของ RTO ลงมากเพื่อใช้ในดาต้าเซ็นเตอร์ หรือใช้ค่าเริ่มต้นตามเดิมกับเส้นทางอินเทอร์เน็ต → ผลคือ ถ้าต่ำ แค่ความหน่วงชั่วขณะก็ส่งซ้ำทะลัก ถ้าสูง หายทุกครั้งก็ต้องรอนาน → บนหน้าจอ ถ้าใช้ค่าเริ่มต้น แพ็กเก็ตหายครั้งเดียวจะค้างหลายร้อย ms แล้วตามด้วยอาการกรอเร็ว ถ้าลดต่ำเกินไป อาการค้างจะลดลงแต่การส่งซ้ำโดยไม่จำเป็นพุ่งจนเปลืองแบนด์วิดท์
- อาการ
- ค้าง, กรอเร็ว, อินพุตดีเลย์
- ปัจจัย
- ความหน่วง
- ใครเจอ
- ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- ตลอดเวลา
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- ถ้าใช้ Linux 6.15 ขึ้นไป พิจารณาลดเพดาน RTO ของการเชื่อมต่อเกมด้วย TCP_RTO_MAX_MS (เวลาจนถึงการเลิกเชื่อมต่อก็สั้นลงด้วย จึงควรกำหนดเวลาตัดสินว่าการเชื่อมต่อขาดด้วย TCP_USER_TIMEOUT ไปพร้อมกัน), ลดค่าต่ำสุดของ RTO ด้วย socket option TCP_RTO_MIN_US (6.15 ขึ้นไป) เฉพาะการเชื่อมต่อภายในระหว่างเซิร์ฟเวอร์, พิจารณาใช้ socket option TCP_THIN_LINEAR_TIMEOUTS กับการเชื่อมต่อเกมเท่านั้น เพื่อไม่ให้ RTO ที่เกิดต่อเนื่องเพิ่มเป็นสองเท่า
- งานฝั่งทีมอินฟรา
- ลด rto_min แยกตามเส้นทางเฉพาะการเชื่อมต่อภายในระหว่างเซิร์ฟเวอร์, เส้นทางอินเทอร์เน็ตคงค่าเริ่มต้นไว้แต่เสริมด้วย RACK-TLP และการตั้งค่า thin stream (tcp_thin_linear_timeouts)
- ตัวเลขที่ควรรู้
- RTO ของ Linux = เวลาไปกลับ + max(200 ms, ส่วนเบี่ยงเบนของ RTT×4) ล้มเหลวแต่ละครั้งจะเพิ่มเป็นสองเท่า สูงสุด 120 วินาที Linux 6.15 ขึ้นไปลดเพดานนี้ลงได้ถึง 1 วินาทีด้วย TCP_RTO_MAX_MS
- บนกราฟ
- สูงตลอดตั้งแต่แรก · RTO ต่อการเชื่อมต่อ, จำนวน RTO ที่ไม่จำเป็น
- จุดที่ต้องดู
- การตั้งค่าต่ำสุดของ RTO บนเซิร์ฟเวอร์ (rto_min ใน ip route show, Linux 6.11 ขึ้นไปดู sysctl net.ipv4.tcp_rto_min_us) กับ rto และ rtt ใน ss -ti และค่าที่เพิ่มขึ้นของ TcpExtTCPSpuriousRTOs ใน nstat
- สัญญาณว่าใช่
- บนเซิร์ฟเวอร์ที่ลดค่าต่ำสุดลง rto ของการเชื่อมต่ออินเทอร์เน็ตแนบชิด rtt และ TcpExtTCPSpuriousRTOs เพิ่มขึ้นมาก ถ้าใช้ค่าเริ่มต้นตามเดิม rto ของการเชื่อมต่อเกมสูงกว่า rtt ตั้งแต่ 200 ms ขึ้นไป และแพ็กเก็ตหายแต่ละครั้งจะหยุดนานเท่านั้น
- สัญญาณว่าไม่ใช่
- rto เป็นไปตามสูตรปกติ (rtt + ราว 200 ms) และ RTO ที่ไม่จำเป็นก็น้อย แต่การหยุดนานผิดปกติ: น่าจะเป็นฝั่งแพ็กเก็ตหายต่อเนื่องหรือวิธีกู้คืน (“thin stream กู้คืนช้า”, “อุปกรณ์กลางทางตัด TCP option ทิ้ง”)
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
แหล่งอ้างอิง
- RFC 6298: Computing TCP's Retransmission Timer IETF
RTO = SRTT + max(G, 4·RTTVAR), แนะนำอย่างน้อย 1 วินาที, เพิ่มเป็นสองเท่าทุกครั้งที่ล้มเหลว, ถ้าจะกำหนดค่าสูงสุดต้องไม่น้อยกว่า 60 วินาที - include/net/tcp.h Linux kernel
TCP_RTO_MIN ของ Linux 200 ms, TCP_RTO_MAX 120 วินาที - net/ipv4/tcp_input.c Linux kernel
RTO ของ Linux คือ SRTT + rttvar และ rttvar จะไม่ต่ำกว่าค่าต่ำสุดของ RTO (ค่าเริ่มต้น 200 ms) - tcp: add the ability to control max RTO Linux kernel
เพิ่ม socket option TCP_RTO_MAX_MS (1–120 วินาที) ตั้งแต่ Linux 6.15 - tcp: add sysctl_tcp_rto_min_us Linux kernel
เพิ่ม tcp_rto_min_us ซึ่งเป็นค่าต่ำสุดของ RTO เริ่มต้นของทั้งเซิร์ฟเวอร์ ตั้งแต่ Linux 6.11 - tcp: support TCP_RTO_MIN_US for set/getsockopt use Linux kernel
เพิ่ม socket option TCP_RTO_MIN_US สำหรับกำหนดค่าต่ำสุดของ RTO รายซ็อกเก็ต ตั้งแต่ Linux 6.15 - IP Sysctl Linux kernel
tcp_rto_min_us ค่าเริ่มต้น 200000 (ตัวเลือกเส้นทาง rto_min และ socket option TCP_RTO_MIN_US มีผลก่อน), tcp_rto_max_ms 1,000–120,000 (ค่าเริ่มต้น 120,000), tcp_thin_linear_timeouts - ip-route(8) — Linux manual page iproute2
ตัวเลือก rto_min รายเส้นทาง: ค่าต่ำสุดของ RTO เมื่อสื่อสารกับปลายทางนั้น - Thin-streams and TCP Linux kernel
ใช้ TCP_THIN_LINEAR_TIMEOUTS ปิด exponential backoff เฉพาะการเชื่อมต่อแบบ thin stream ได้ - tcp(7) — Linux manual page Linux man-pages
TCP_USER_TIMEOUT: เวลาที่รอข้อมูลที่ยังไม่ได้รับการยืนยันก่อนปิดการเชื่อมต่อ - ss(8) — Linux manual page iproute2
rto (ms) และ rtt ใน ss -i - SNMP counter Linux kernel
TcpExtTCPSpuriousRTOs: RTO ที่ไม่จำเป็นซึ่ง F-RTO ตรวจพบ
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: ต้นเหตุของการส่งซ้ำใน TCP
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง