คู่มือเกมแลค › ต้นเหตุของการส่งซ้ำใน TCP
บัฟเฟอร์ตื้นล้นเพราะ burst จากฝั่งส่ง Sender bursts overflow shallow buffers
ID สาเหตุ rt-burst · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา), อินฟราเครือข่าย (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าเซิร์ฟเวอร์ส่งอัปเดตของผู้เล่นหลายพันคนออกไปรวดเดียวในทุกทิก บัฟเฟอร์เล็ก ๆ ของสวิตช์หรือขีดจำกัดชั่วขณะของคลาวด์จะล้นภายในไม่ถึง 1 ms และแพ็กเก็ตบางส่วนถูกทิ้ง
ทำไม ส่งแพ็กเก็ตของทุกคนออกไปพร้อมกันตอนเริ่มทิก → ผลคือ บัฟเฟอร์ของพอร์ตสวิตช์ที่ทราฟฟิกจากหลายเซิร์ฟเวอร์มารวมกัน (หลายร้อย KB ถึงหลาย MB ต่อพอร์ต) หรือขีดจำกัดของอินสแตนซ์คลาวด์ล้นชั่วขณะ (อัตราการใช้งานเฉลี่ยต่ำ) → บนหน้าจอ หลายคนวาร์ปหรือหยุดแวบพร้อมกัน, ดูจากเมตริกค่าเฉลี่ยจะไม่เห็นสาเหตุ
- อาการ
- วาร์ป, ค้าง, กรอเร็ว
- ปัจจัย
- แพ็กเก็ตหาย
- ใครเจอ
- บางจุด/บางแชนแนล, ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- ตอนคนแห่มารวมกัน
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา), อินฟราเครือข่าย (ทีมอินฟรา)
- งานฝั่งทีมพัฒนาเกม
- กระจายการส่งของหนึ่งทิกให้ทั่วช่วงเวลาของทิก (การที่การเชื่อมต่อหลายพันรายการกองรวมกันตอนเริ่มทิก pacing ต่อการเชื่อมต่อช่วยได้ไม่มาก), เหลื่อมเวลาเริ่มทิกของแต่ละเซิร์ฟเวอร์, จำกัดความเร็วสูงสุดของการเชื่อมต่อที่ส่งข้อมูลใหญ่ด้วย SO_MAX_PACING_RATE
- งานฝั่งทีมอินฟรา
- เครื่องเซิร์ฟเวอร์/OS: จำกัดความเร็วส่งรวมของทั้งเซิร์ฟเวอร์ (shaper ของ OS เซิร์ฟเวอร์, tc ของ Linux), เกลี่ยการส่งรวดเดียวของการเชื่อมต่อเดียวให้สม่ำเสมอด้วย pacing (คิว fq ของ Linux, BBR) เครือข่าย: ใช้สวิตช์ที่บัฟเฟอร์ใหญ่, ตรวจตัวนับการทิ้งขาออกของพอร์ตสวิตช์ด้วยช่วงเวลาสั้น ๆ (ดูจากอัตราการใช้งานเฉลี่ยจะไม่เห็น)
- ตัวเลขที่ควรรู้
- พอร์ต 10 Gbps ส่งข้อมูลได้ราว 1.25 MB ใน 1 ms ถ้าทิกของหลายเซิร์ฟเวอร์ตรงกันแล้วมารวมที่พอร์ตเดียว บัฟเฟอร์จะเต็มในพริบตา
- บนกราฟ
- สูงตามจำนวนคนและโหลด · จำนวนการทิ้งขาออกของพอร์ตสวิตช์, อัตราการส่งซ้ำ
- จุดที่ต้องดู
- การทิ้งขาออก (ifOutDiscards) ของพอร์ตสวิตช์ที่เซิร์ฟเวอร์ต่ออยู่และพอร์ตชั้นบนถัดไป เก็บทุกไม่กี่วินาที ถ้าเป็นคลาวด์ดู bw_out_allowance_exceeded และ pps_allowance_exceeded จาก ethtool -S เก็บการส่งซ้ำในช่วงเวลาเดียวกันด้วย bcc tcpretrans แล้วเทียบกัน
- สัญญาณว่าใช่
- อัตราการใช้งานเฉลี่ยรายนาทีต่ำ แต่การทิ้งขาออกหรือ allowance exceeded เพิ่มขึ้น และเพิ่มตามจำนวนผู้เล่นออนไลน์พร้อมกันและจำนวนคนที่รวมตัวอยู่จุดเดียว การส่งซ้ำเกิดในหลายการเชื่อมต่อของเซิร์ฟเวอร์นั้นในจังหวะเดียวกัน โดยไม่กระจุกที่ช่วง IP ของผู้เล่นกลุ่มใด (ISP/พื้นที่)
- สัญญาณว่าไม่ใช่
- CRC และ input error ที่พอร์ตเดียวกันเพิ่มขึ้นด้วย: น่าจะเป็น “ข้อผิดพลาดทางกายภาพ” ถ้าตัวนับการทิ้งของ NIC หรือ softnet dropped ที่เซิร์ฟเวอร์ฝั่งรับเพิ่มขึ้น น่าจะเป็น “เครื่องเซิร์ฟเวอร์ฝั่งรับทิ้งแพ็กเก็ต”
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- pacing ทำงานแยกกันในแต่ละการเชื่อมต่อ การกองรวมที่เกิดจากการเชื่อมต่อหลายพันรายการต่างส่งแพ็กเก็ตหนึ่งสองตัวตอนเริ่มทิก pacing ต่อการเชื่อมต่อช่วยได้ไม่มาก เซิร์ฟเวอร์เกมต้องกระจายจังหวะการส่งเอง ในทางกลับกัน เมื่อการเชื่อมต่อเดียวส่งข้อมูลใหญ่ NIC จะหั่นข้อมูลหลายสิบ KB เป็นขนาดแพ็กเก็ตแล้วส่งออกติดกัน (TSO) การกองรวมแบบนี้ pacing ช่วยกระจายได้ดี
แหล่งอ้างอิง
- High-Resolution Measurement of Data Center Microbursts Meta
burst ของสวิตช์ระดับแร็กในดาต้าเซ็นเตอร์ตั้งแต่ 70% ขึ้นไปจบภายในหลายสิบ µs และอัตราการใช้งานเฉลี่ยรายนาทีสัมพันธ์กับการดรอปน้อย (IMC 2017) - tc-fq(8) — Linux manual page iproute2
คิว fq ทำ pacing แยกตามซ็อกเก็ต (การเชื่อมต่อ) และกำหนดความเร็วสูงสุดต่อการเชื่อมต่อด้วย SO_MAX_PACING_RATE - net/ipv4/tcp_bbr.c Linux kernel
BBR กำหนด pacing_rate จากแบนด์วิดท์คอขวดที่ประเมินได้แล้วส่งตามนั้น - IP Sysctl Linux kernel
TCP กำหนดขนาดเฟรม TSO ตามความเร็วของ flow (สูงสุด 64 KB, tcp_min_tso_segs) - Monitor network performance for ENA settings on your EC2 instance AWS
bw_out_allowance_exceeded และ pps_allowance_exceeded: จำนวนแพ็กเก็ตที่ถูกเข้าคิวหรือถูกทิ้งเพราะเกินขีดจำกัดแบนด์วิดท์หรือจำนวนแพ็กเก็ตต่อวินาทีของอินสแตนซ์ - RFC 2863: The Interfaces Group MIB IETF
ifOutDiscards: จำนวนแพ็กเก็ตที่ถูกทิ้งโดยไม่ได้ส่งออกทั้งที่ไม่มี error ด้วยเหตุผล เช่น เพื่อคืนพื้นที่บัฟเฟอร์ - Demonstrations of tcpretrans, the Linux eBPF/bcc version IO Visor
แสดงที่อยู่และพอร์ตของอีกฝั่งและสถานะการเชื่อมต่อ หนึ่งบรรทัดต่อการส่งซ้ำแต่ละครั้ง
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: ต้นเหตุของการส่งซ้ำใน TCP
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (วาร์ป)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง