# Linuxでロードバランサやキャッシュサーバをマルチコアスケールさせるためのカーネルチューニング [[Yuuki Tsubouchi]](坪内佑樹)が 2015 年 3 月 31 日に yuuk.io に公開したブログ記事。高パケットレートなネットワークアプリケーション(HAProxy・nginx・memcached 等)がマルチコア環境でも CPU0 の softirq に負荷が集中する問題を解説し、[[RFS(Receive Flow Steering)]] を中心としたカーネルチューニング手法を実験で検証した実践的技術記事。 ## 問題の核心 64 バイトフレームで 1 Gbps トラヒックの場合、約 150 万回/秒のハードウェア割り込みが発生する。シングルキュー NIC では、このすべてが CPU0 の割り込みハンドラで処理される(`%soft` が 100% に達しても他コアは遊休)。 ## マルチコアスケールの技術体系 ### [[RSS(Receive Side Scaling)]] マルチキュー NIC が、4 タプル(送受信 IP・ポート)のハッシュで複数キューにパケットを分散し、各キューを異なる CPU コアへ割り当てる。NIC ハードウェアとドライバの両方が対応している必要があり、ハードウェア依存が高い。 ### [[RPS(Receive Packet Steering)]] [[RSS(Receive Side Scaling)]] のソフトウェア実装版。シングルキュー NIC でも機能する。割り込みを受けた CPU がコア間割り込み(IPI)で他 CPU コアにプロトコル処理を分散する。 ```bash echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus ``` ### [[RFS(Receive Flow Steering)]] [[RPS(Receive Packet Steering)]] を拡張し、アプリケーションプロセスの CPU キャッシュ局所性を考慮する仕組み。フローテーブルで「プロセスが最後に実行された CPU コア」を記録し、次回の受信処理も同じコアで実行する。 ```bash echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt echo 32768 > /proc/sys/net/core/rps_sock_flow_entries ``` | パラメータ | 説明 | |---|---| | `rps_cpus` | 分散先 CPU コアのビットマスク(`f` = 4 コア全部) | | `rps_flow_cnt` | NIC キューごとのフローテーブルエントリ数(通常 `rps_sock_flow_entries` / NIC キュー数) | | `rps_sock_flow_entries` | グローバルソケットフローテーブルのエントリ数(目安: 同時接続数 × 2) | ## 実験結果 16 コアシステムで RFS 有効化前後を比較: - **有効化前**: CPU0 の softirq・user・sys が集中(softirq 15.31%、他コアほぼ遊休) - **有効化後**: 複数コアに分散、Starlet ベースのアプリケーションで応答速度 **約 10% 向上** - **対応アプリケーション**: HAProxy・pgpool・Varnish・memcached で副作用なく動作確認済み ## 補足技術 | 技術 | 概要 | |---|---| | NAPI | 割り込みドリブン→ポーリング切り替えでコンテキストスイッチ削減 | | チェックサムオフロード | チェックサム計算を NIC に委譲([[スマートNICオフロード]] の一形態) | | 割り込みコアレッシング | 割り込み発生頻度を抑制してスループット向上 | ## 位置づけ 本記事は 2015 年時点の実践的チューニングガイドとして書かれており、現在も有効な手法を解説している。RFS は Linux 2.6.35 以降で利用可能で、ハードウェア依存がない点がポイント。[[スマートNICオフロード]] による最新のハードウェアオフロードとは異なるアプローチ(ソフトウェアレイヤでの負荷分散)であり、両者は補完関係にある。