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

游戏卡顿白皮书 › TCP 重传的根本原因

突发发送导致浅缓冲区溢出 Sender bursts overflow shallow buffers

原因 ID rt-burst · 主责 研发团队·服务器开发 · 配合 运维团队·系统运维, 运维团队·网络运维

在含图示和实验的完整版中打开此卡片 →

服务器每个 tick 在一瞬间集中发出几千人份的更新,交换机的小缓冲区或云平台的瞬时上限不到 1 ms 就会溢出,一部分包被丢弃。

起因 tick 开始的瞬间,把发给所有人的数据包一次性发出 → 结果 多台服务器流量汇聚的交换机端口缓冲区(每个端口几百 KB 到几 MB)或云实例的上限瞬间被冲破(平均利用率很低) → 画面表现 多名玩家同时瞬移或顿一下,看平均值指标找不到原因

症状
瞬移, 卡住, 快进
因素
丢包
谁会遇到
特定地点/分线, 全服
何时出现
人多的时候
负责方
主责 研发团队·服务器开发 · 配合 运维团队·系统运维, 运维团队·网络运维
研发团队要做的事
把一个 tick 的发送分散到整个 tick 内(几千个连接在 tick 开始时扎堆,靠按连接的平滑发送很难解决);错开各服务器的 tick 起始时刻;发送大数据的连接用 SO_MAX_PACING_RATE 设置速率上限。
运维团队要做的事
服务器/OS:给整台服务器的发送速率设上限(服务器操作系统的流量整形器,Linux tc);单个连接的突发发送用平滑发送(Linux fq 队列、BBR)摊平。网络:换用大缓冲交换机;以较短间隔检查交换机端口的出方向丢弃计数器(看平均利用率发现不了)。
数值参考
10 Gbps 端口 1 ms 能发送的量约为 1.25 MB。多台服务器的 tick 撞在一起、涌向同一个端口时,缓冲区瞬间就满了。
监控图上
随人数/负载上升 · 交换机端口出方向丢弃数、重传率
查看位置
以几秒的间隔采集服务器所连交换机端口及其上一级端口的出方向丢弃(ifOutDiscards);云上看 ethtool -S 的 bw_out_allowance_exceeded、pps_allowance_exceeded。用 bcc tcpretrans 采集同一时刻的重传并对照
确认依据
分钟级平均利用率很低,出方向丢弃或 allowance 超限却在增加,且随同时在线人数和同一地点的聚集人数增大。重传在该服务器的多个连接上同一时刻发生,并不集中在特定玩家 IP 网段(运营商、地区)
排除依据
同一端口的 CRC、入方向错误也一起增加,看“物理层错误”。接收端服务器的网卡丢弃计数器或 softnet dropped 增加,看“接收端服务器主机丢包”
确认手段
运维工具即可确认(无需游戏代码)
深入了解
平滑发送(pacing)按连接分别起作用。几千个连接在 tick 开始时各发一两个包形成的扎堆,按连接的平滑发送很难化解,需要游戏服务器自己错开发送时间点。反过来,单个连接发送大数据时,网卡会把几十 KB 的数据切成数据包大小连续发出(TSO),这种突发靠平滑发送就能很好地摊开。

出处

  1. High-Resolution Measurement of Data Center Microbursts Meta
    数据中心机架交换机的突发 70% 以上在几十 µs 内结束,分钟级平均利用率与丢包的关系很弱(IMC 2017)
  2. tc-fq(8) — Linux manual page iproute2
    fq 队列按 socket(连接)做平滑发送,用 SO_MAX_PACING_RATE 设定每个连接的最大速率
  3. net/ipv4/tcp_bbr.c Linux kernel
    BBR 根据估算出的瓶颈带宽确定 pacing_rate 并按此发送
  4. IP Sysctl Linux kernel
    TCP 根据流的速率确定 TSO 帧大小(最大 64 KB,tcp_min_tso_segs)
  5. Monitor network performance for ENA settings on your EC2 instance AWS
    bw_out_allowance_exceeded、pps_allowance_exceeded:因超出实例的带宽或每秒包数上限而被排队或丢弃的数据包数
  6. RFC 2863: The Interfaces Group MIB IETF
    ifOutDiscards:没有错误,却因腾出缓冲区空间等原因没有发出、直接丢弃的数据包数
  7. Demonstrations of tcpretrans, the Linux eBPF/bcc version IO Visor
    每次重传输出一行,显示对端地址、端口和连接状态

相关原因

同一层:TCP 重传的根本原因

其他层中同样导致“瞬移”的原因

查看含图示和实验的原卡片