遊戲 Lag 白皮書 › L6 伺服器網路卡
NIC 中斷集中在單一核心 Single-queue NIC / no RSS
原因 ID nic-irq · 主要負責 基礎設施團隊(伺服器基礎設施)
在含圖解與實驗的完整版中開啟卡片 →
NIC 只把封包到達的中斷(interrupt)送給一個 CPU 核心時,那個核心就會成為瓶頸。
為什麼 只有一個接收佇列,或是負責分散到多個核心的 RSS 被關閉 → 於是 單一核心達到 100%,無法及時取出封包 → 畫面上 人潮湧入時,整個伺服器出現封包遺失與延遲(瞬移、輸入延遲)
- 症狀
- 瞬移, 拉回, 輸入延遲
- 因素
- 遺失, 延遲
- 誰會遇到
- 整個伺服器
- 何時
- 人潮湧入時
- 負責單位
- 主要負責 基礎設施團隊(伺服器基礎設施)
- 基礎設施團隊要做的事
- 設定 RSS(由 NIC 分散)與 RPS(由 kernel 分散),把中斷分散到多個核心;讓 UDP 連同 port 一起計算來分配佇列(ethtool -N 的 rx-flow-hash udp4 sdfn);把處理中斷的核心與遊戲 tick 執行緒的核心分開;監看各核心的 %soft。
- 數值參考
- 一個核心經由 kernel 能處理的量,依封包大小與設定而定,大約是每秒數十萬個封包。如果各核心的使用率中,接收處理所占的比例(mpstat 的 %soft)只集中在一個核心,就是這種情況。
- 圖表上
- 碰到上限後持平 · 各核心 %soft、每秒接收封包數
- 查看位置
- 用 mpstat -P ALL 1 查看各核心的 %soft(軟體中斷處理比例),用 /proc/interrupts 確認各 NIC 佇列的中斷送往哪個核心,用 ethtool -l 確認佇列數,用 ethtool -S 確認各佇列的封包數(名稱依驅動程式而異)
- 符合的跡象
- 只有一個核心的 %soft 貼近 100%,其餘核心很閒,中斷與封包集中在單一佇列。從那時起每秒接收封包數無法再往上
- 不符合的跡象
- %soft 平均分散在多個核心時,就不是這個原因。CPU 很閒卻有封包遺失時,是「超過雲端 PPS 上限」或「Ring buffer 不足」
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
- 深入了解
- 即使有多個佇列,如果大部分流量來自閘道、proxy 這類少數幾個位址,還是會集中到同一個佇列。部分 NIC 的預設設定只看位址來分配 UDP 的佇列,要改成連同 port 一起看,才會平均分散。
出處
- Scaling in the Linux Networking Stack Linux kernel
RSS(由 NIC 分散到多個接收佇列)、RPS(由 kernel 分散),每個佇列各自有中斷並分配到多個核心的設定,接收中斷處理成為瓶頸時建議使用 RSS - How to receive a million packets per second Cloudflare
單一接收佇列只送往一個核心時,實測該核心在每秒約 35 萬~43 萬個封包就卡住,也有 NIC 只用 IP 位址對 UDP 做雜湊、全部集中到一個佇列的案例 - ethtool(8) — Linux manual page ethtool
用 ethtool -N rx-flow-hash udp4 把 port(f、n)也納入 UDP 雜湊的選項 - mpstat(1) — Linux manual page sysstat
%soft:CPU 用於軟體中斷處理的時間比例,-P ALL 顯示各核心
相關原因
同一層:L6 伺服器網路卡
同一症狀(瞬移)在其他層的原因
查看含圖解與實驗的完整版卡片