ゲームラグ白書 › L7 サーバーOS(カーネル)
カーネルのソケットバッファ不足 Small socket buffers
原因ID so-sockbuf · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
送受信バッファが小さいと、バーストトラフィックが集中したときに、UDPで受信したパケットは破棄され、TCPの送信はバッファに空きがなくブロックされます。
なぜ SO_SNDBUF・SO_RCVBUFがデフォルト値のまま、または小さすぎる → すると バーストや、受信スレッドが一瞬止まった間にUDPの受信バッファがあふれて破棄、TCPは送信バッファに空きがなく待機 → 画面では ワープ(UDPのパケットロス)または早送り(TCPの待機)
- 症状
- ワープ, 早送り
- 要因
- パケットロス, ストール
- 誰に起きるか
- サーバー全体
- いつ
- 人が集中したとき
- 担当
- 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
- ゲーム開発チームの対応
- トラフィックに見合ったバッファサイズ(SO_SNDBUF・SO_RCVBUF)をコードで設定、TCPはサイズを明示するとLinuxの自動サイズ調整が無効になるので注意、大きくしすぎると古いデータがバッファにたまって遅延が増えるので適度に、受信スレッドが止まらないようにする。
- インフラチームの対応
- カーネルの上限(rmem_max・wmem_max。コードで設定したバッファサイズもこの値を超えられない)とデフォルト値(rmem_default)の調整、バッファあふれのカウンター(RcvbufErrors)の監視。
- 数値の目安
- LinuxのUDP受信バッファのデフォルト値は約208KBです。小さなパケットでも1個でカーネルメモリを実際のサイズよりはるかに多く消費するため、数十〜数百個で満杯になります。毎秒10万個を受信するサーバーなら、受信スレッドが数ms止まるだけであふれます。
- グラフでは
- 不定期なスパイク · UDP受信バッファのあふれ(UdpRcvbufErrors)
- 確認箇所
- nstat -azでUdpRcvbufErrorsの増加量を、ss -uamnでskmem(rbは受信バッファサイズ、dはソケットに入れられず破棄したパケット数)を確認し、TCPはss -tmのskmemで送信待ちメモリ(w)が送信バッファサイズ(tb)に達しているかを確認
- 該当する場合
- バーストや受信スレッドが止まった時刻にUdpRcvbufErrors(またはソケットのd)が増え、rbがデフォルト値(約208KB)付近。TCPはwがtbに張り付いたままsendがブロック
- 該当しない場合
- カウンターが増えていないのにパケットロスがあれば、NICの段階(「リングバッファ不足」)かネットワーク区間
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- socket(7) — Linux manual page Linux man-pages
SO_RCVBUF・SO_SNDBUFのデフォルト値はrmem_default・wmem_default、上限はrmem_max・wmem_max、設定値はカーネルが2倍にして確保 - include/net/sock.h (Linux v6.18) Linux kernel
デフォルトのソケットバッファを、sk_buffのオーバーヘッドを含む256バイトのパケット256個分(SKB_TRUESIZE(256)×256)と定義、小さなフレームもsk_buff+MTU分として計算される(約208KBはx86-64での計算値) - IP Sysctl Linux kernel
tcp_rmem・tcp_wmem:SO_RCVBUF・SO_SNDBUFを明示すると、そのソケットの自動サイズ調整が無効になる - net/ipv4/udp.c (Linux v6.12) Linux kernel
UDPの受信キューがソケットバッファサイズを超えると即座に破棄し、RcvbufErrorsを加算 - net/ipv4/proc.c (Linux v6.12) Linux kernel
nstatが表示するカウンター名:UdpグループのRcvbufErrors・SndbufErrors - ss(8) — Linux manual page iproute2
-mのskmem:rbは受信バッファサイズ、tbは送信バッファサイズ、wは送信待ちメモリ、dはソケットに入れる前に破棄したパケット数
あわせて読みたい原因
同じ層:L7 サーバーOS(カーネル)
同じ症状(ワープ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る