# 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オフロード]] による最新のハードウェアオフロードとは異なるアプローチ(ソフトウェアレイヤでの負荷分散)であり、両者は補完関係にある。