遊戲 Lag 白皮書 › TCP 重傳的根本原因
突發傳送造成淺緩衝區溢位 Sender bursts overflow shallow buffers
原因 ID rt-burst · 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(伺服器基礎設施), 基礎設施團隊(網路基礎設施)
在含圖解與實驗的完整版中開啟卡片 →
伺服器每個 tick 把數千人份的更新在一瞬間集中送出時,交換器的小緩衝區或雲端的瞬間上限不到 1ms 就會溢位,部分封包因此被丟棄。
為什麼 每個 tick 開始的瞬間,把要送給所有人的封包一次送出 → 於是 匯集多台伺服器流量的交換器 port 緩衝區(每個 port 數百 KB~數 MB)或雲端執行個體的上限瞬間溢位(平均使用率很低) → 畫面上 多人同時瞬移、頓一下,看平均指標找不出原因
- 症狀
- 瞬移, 定格, 快轉
- 因素
- 遺失
- 誰會遇到
- 特定地點/頻道, 整個伺服器
- 何時
- 人潮湧入時
- 負責單位
- 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(伺服器基礎設施), 基礎設施團隊(網路基礎設施)
- 遊戲開發團隊要做的事
- 把一個 tick 的傳送分散到整個 tick 內送出(數千條連線在 tick 開始時集中送出,靠各連線的 pacing 很難解決)、錯開各伺服器的 tick 開始時間、傳送大量資料的連線用 SO_MAX_PACING_RATE 設定速度上限。
- 基礎設施團隊要做的事
- 伺服器設備/OS:設定整台伺服器的傳送速度上限(伺服器 OS 的 shaper,Linux tc),單一連線的集中送出用 pacing(Linux fq 佇列、BBR)打散。網路:採用大緩衝區交換器、以短間隔檢查交換器 port 的輸出丟棄計數器(看平均使用率看不出來)。
- 數值參考
- 10Gbps port 在 1ms 內能送出的量約 1.25MB。多台伺服器的 tick 剛好重疊、集中到同一個 port 時,緩衝區一下子就滿了。
- 圖表上
- 隨人數/負載上升 · 交換器 port 輸出丟棄數、重傳率
- 查看位置
- 以幾秒的間隔收集伺服器所接交換器 port 及其上層 port 的輸出丟棄(ifOutDiscards),雲端環境則看 ethtool -S 的 bw_out_allowance_exceeded、pps_allowance_exceeded。用 bcc tcpretrans 收集同一時間點的重傳來對照
- 符合的跡象
- 以分鐘為單位的平均使用率很低,輸出丟棄或 allowance 超出次數卻增加,而且隨同時上線人數與集中在同一處的人數變多。重傳在同一瞬間出現在該伺服器的多條連線上,沒有集中在特定玩家的 IP 網段(電信業者、地區)
- 不符合的跡象
- 同一個 port 的 CRC、輸入錯誤一起增加時是「實體層錯誤」。接收端伺服器的 NIC 丟棄計數器或 softnet dropped 增加時是「接收端伺服器主機丟棄封包」
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
- 深入了解
- Pacing 是每條連線各自運作。數千條連線在 tick 開始時各送一兩個封包所形成的集中,靠各連線的 pacing 很難打散,必須由遊戲伺服器自己把傳送時間點分開。反過來,單一連線傳送大量資料時,NIC 會把數十 KB 的資料切成封包大小接連送出(TSO),這種集中 pacing 就能有效打散。
出處
- High-Resolution Measurement of Data Center Microbursts Meta
資料中心機櫃交換器的突發流量有 70% 以上在數十 µs 內結束,以分鐘為單位的平均使用率與丟棄的關聯很弱(IMC 2017) - tc-fq(8) — Linux manual page iproute2
fq 佇列對每個 socket(連線)做 pacing,並以 SO_MAX_PACING_RATE 設定每條連線的最大速度 - net/ipv4/tcp_bbr.c Linux kernel
BBR 依估計的瓶頸頻寬決定 pacing_rate 來傳送 - IP Sysctl Linux kernel
TCP 依該流的速率決定 TSO 訊框大小(最大 64KB,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:沒有偵測到錯誤,卻因要騰出緩衝區空間等原因而沒有送出、直接丟棄的封包數 - Demonstrations of tcpretrans, the Linux eBPF/bcc version IO Visor
每次重傳顯示一行,包含對端位址、port 與連線狀態
相關原因
同一層:TCP 重傳的根本原因
同一症狀(瞬移)在其他層的原因
查看含圖解與實驗的完整版卡片