Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
10GbE時代のネット
ワークI/O高速化
Takuya ASADA<syuu@freebsd.org>
13年6月7日金曜日
はじめに
• 10GbE、40GbEなどの極めて高速な通信をサ
ポートするNICが、PCサーバの領域でも使わ
れるようになってきている
• このような速度の通信をソフトウェア
(OS)で処理し高い性能を得るには様々な
障害があり、ハードウェア・ソフトウェア
両面の実装を見直す必要がある
13年6月7日金曜日
今日のトピック
1. 割り込みが多すぎる
2. プロトコル処理が重い
3. 複数のCPUでパケット処理したい
4. データ移動に伴うレイテンシの削減
5. プロトコルスタックを経由しないネットワ
ークIO
13年6月7日金曜日
1. 割り込みが多すぎる
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年6月7日金曜日
割り込みが多すぎる
• NICの性能向上によって、一定時間に
NICが処理できるパケット数が飛躍的に
増加
• 1パケット毎に割り込みが来ると、通
信量が多いときにコンテキストスイッ
チ回数が増えすぎ性能が劣化
13年6月7日金曜日
旧来のパケット受信処理
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
ハードウェア割り込み
↓
受信キューにキュー
イング
↓
ソフトウェア割り込
みスケジュール
13年6月7日金曜日
旧来のパケット受信処理
• 1パケット受信するたびに割り込みを
受けて処理を行っている
• 64byte frameの最大受信可能数:
• GbE:約1.5Mpps(150万)
• 10GbE:約15Mpps(1500万)
13年6月7日金曜日
割り込みを無効にする?
• ポーリング方式
• NICの割り込みを禁止し、代わりにクロック割り込み
を用いて定期的に受信キューをチェック
• デメリット:レイテンシが上がる・定期的にCPUを起
こす必要がある
• ハイブリッド方式
• 通信量が多く連続してパケット処理を行っている時の
み割り込みを無効化してポーリングで動作
13年6月7日金曜日
NAPI(ハイブリッド方式)
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる
まで繰り返し
ハードウェア割り込み
↓
割り込み無効化&
ポーリング開始
↓
パケットが無くなっ
たら割り込み有効化
13年6月7日金曜日
Interrupt Coalescing
• NICがOS負荷を考慮して割り込みを間
引く
• パケット数個に一回割り込む、
或いは一定期間待ってから割り込む
• デメリット:レイテンシが上がる
13年6月7日金曜日
Interrupt Coalescingの効果
• Intel 82599(ixgbe)でInterrupt Coalescing無効、
有効(割り込み頻度自動調整)で比較
• MultiQueue, GRO, LRO等は無効化
• iperfのTCPモードで計測
interrupts throughput packets CPU%(sy+si)
無効
有効
46687 int/s 7.82 Gbps 660386 pkt/s 97.6%
7994 int/s 8.24 Gbps 711132 pkt/s 79.6%
13年6月7日金曜日
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる
まで繰り返し
2.プロトコル処理が重い
13年6月7日金曜日
プロトコル処理が重い
• 特に小さなパケットが大量に届く場合にプ
ロトコル処理でCPU時間を大量に使ってしま
う
• パケット数分プロトコルスタックが呼び出
される
例:64byte frameの場合
→理論上の最大値は1500万回/s
13年6月7日金曜日
TOE
(TCP Offload Engine)
• OSでプロトコル処理するのをやめて、NICで処理する
• デメリット
• セキュリティ:TOEにセキュリティホールが生じても、OS
側から対処が出来ない
• 複雑性:OSのネットワークスタックをTOEで置き換えるに
はかなり広範囲の変更が必要
メーカによってTOEの実装が異なり共通インタフェース定義
が困難
• Linux:サポート予定無し
13年6月7日金曜日
Checksum Offloading
• IP・TCP・UDP checksumの計算をNICで
行う
13年6月7日金曜日
Checksum Offloadingの効果
• Intel 82599(ixgbe)で比較
• iperfのTCPモードで計測
• MultiQueueは無効化
• ethtool -K ix0 rx off
throughput CPU%(sy+si)
無効
有効
8.27 Gbps 86
8.27 Gbps 85.2
13年6月7日金曜日
LRO
(Large Receive Offload)
• NICが受信したTCPパケットを結合し、
大きなパケットにしてからOSへ渡す
• プロトコルスタックの呼び出し回数を
削減
• LinuxではソフトウェアによるLROが実
装されている(GRO)
13年6月7日金曜日
LROが無い場合
• パケット毎にネットワークスタックを
実行
seq 10000 seq 10001 seq 10002 seq 10003
←1500bytes→
To network stack
13年6月7日金曜日
LROが有る場合
• パケットを結合してからネットワークスタックを
実行、ネットワークスタックの実行回数を削減
seq 10000 seq 10001 seq 10002 seq 10003
←1500bytes→
To network stack
big one packet
13年6月7日金曜日
GROの効果
• Intel 82599(ixgbe)で比較
• MultiQueueは無効化
• iperfのTCPモードで計測
• ethtool -K ix0 gro off
packets
network stack
called count throughput CPU%(sy+si)
無効
有効
632139 pkt/s 632139 call/s 7.30 Gbps 97.6%
712387 pkt/s 47957 call/s 8.25 Gbps 79.6%
13年6月7日金曜日
TSO
(TCP Segmentation Offload)
• LROの逆
• パケットをフラグメント化せずに送信
NICがパケットをMTUサイズに分割
• OSはパケット分割処理を省略出来る
• LinuxではソフトウェアによるGSO、
ハードウェアによるTSO/UFOをサポート
13年6月7日金曜日
TSOの効果
• Intel 82599(ixgbe)で比較
• MultiQueueは無効化
• iperfのTCPモードで計測
• ethtool -K ix0 gso off tso off
packets throughput CPU%(sy+si)
無効
有効
247794 pkt/s 2.87 Gbps 53.5%
713127 pkt/s 8.16 Gbps 26.8%
13年6月7日金曜日
3.複数のCPUでパケット処理したい
cpu0
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる
まで繰り返し
cpu1
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる
まで繰り返し
13年6月7日金曜日
ソフト割り込みが
1つのコアに偏る
13年6月7日金曜日
ソフト割り込みとは?
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる
まで繰り返し
ポーリングから
プロトコル処理まで
→ネットワークIOの
大半部分
13年6月7日金曜日
何故偏る?
ソフト割り込みはNICの割り込みがかかったCPUへ
スケジュールされる
↓
ポーリングからプロトコルスタックの実行まで
ソフト割り込み内で実行される
↓
NICの割り込みがかかっているCPUだけに
負荷がかかる
13年6月7日金曜日
ソフト割り込みが1つのコ
アに偏って性能が出ない
• memcachedなどショートパケットを大
量に捌くワークロードで顕在化
• ソフトウェア割り込みを実行している
CPUがボトルネックになり、性能がス
ケールしなくなる
13年6月7日金曜日
解決方法
• パケットを複数のCPUへ分散させてから
プロトコル処理する仕組みがあれば良い
• 但し、TCPには順序保証が有るので並列
に処理されるとパケットの並べ直し(リ
オーダ)が発生してパフォーマンスが落
ちる
13年6月7日金曜日
TCP Reordering
• シーケンスナンバー通りの順序でパケットが
着信していれば順にバッファへコピーしてい
くだけでよいが…
1 2 3 4 5 6
1 2 3 4 5 6
protocol
processing
user buffer
13年6月7日金曜日
TCP Reordering
1 2 4 5 3 6
1 2 3 4 5 6
protocol
processing
user buffer
reorder
queue
3 4 5
• 順序が乱れているとパケットの並べ直し
(リオーダ)作業が必要になる
13年6月7日金曜日
解決方法(続)
• 1つのフローは1つのCPUで処理され
る方が都合が良い
13年6月7日金曜日
RSS
(Receive Side Scaling)
• CPUごとに別々の受信キューを持つNIC
(MultiQueue NICと呼ばれる)
• 受信キューごとに独立した割り込みを持つ
• 同じフローに属するパケットは同じキューへ、
異なるフローに属するパケットはなるべく別のキュ
ーへ分散
→パケットヘッダのハッシュ値を計算する事により
宛先キューを決定
13年6月7日金曜日
MSI-X割り込み
• PCI Expressでサポート
• デバイスあたり2048個のIRQを持てる
• それぞれのIRQの割り込み先CPUを選べ
る
→1つのNICがCPUコア数分のIRQを持
てる
13年6月7日金曜日
RSSによる
パケット振り分け
NIC
パケットパケットパケット
ハッシュ計算
パケット着信
hash queue
ディスパッチ
参照
RX
Queue
#0
RX
Queue
#1
RX
Queue
#2
RX
Queue
#3
cpu0 cpu1 cpu2 cpu3
受信処理
割り込み
受信処理
■
■
0
1
13年6月7日金曜日
キュー選択の手順
indirection_table[64] = initial_value
input[12] =
{src_addr, dst_addr, src_port, dst_port}
key = toeplitz_hash(input, 12)
index = key & 0x3f
queue = indirection_table[index]
13年6月7日金曜日
RSS導入前
13年6月7日金曜日
RSS導入後
13年6月7日金曜日
RPS
• RSS非対応のオンボードNICをうまくつかってサー
バの性能を向上させたい
• ソフトでRSSを実装してしまおう
• ソフト割り込みの段階でパケットを各CPUへばら
まく
• CPU間割り込みを使って他のCPUを稼動させる
• RSSのソフトウエアによるエミュレーション
13年6月7日金曜日
cpu3cpu2cpu1cpu0
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システム
コール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込み
パケット受信
ハッシュ計算
ディスパッチ
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
backlog
#1
hash queue
参照
■
■
0
1
CPU間
割り込み
backlog
#2
backlog
#3
13年6月7日金曜日
RPSの使い方
# echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
# echo 4096 > /sys/class/net/eth0/queues/rx-0/
rps_flow_cnt
13年6月7日金曜日
RPS導入前
13年6月7日金曜日
RPS導入後
13年6月7日金曜日
RPS netperf result
netperf benchmark result on lwn.net:
e1000e on 8 core Intel
   Without RPS: 90K tps at 33% CPU
   With RPS:    239K tps at 60% CPU
foredeth on 16 core AMD
   Without RPS: 103K tps at 15% CPU
   With RPS:    285K tps at 49% CPU
13年6月7日金曜日
RFS
• プロセス追跡機能をRPSに追加
13年6月7日金曜日
RFS
フローに割り当てら
れたキューが宛先プ
ロセスのCPUと異な
るとオーバヘッドが
発生する
13年6月7日金曜日
RFS
ハッシュテーブルの
設定値を変更する
事でCPUを一致さ
せる事ができる
13年6月7日金曜日
RFSの使い方
# 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
13年6月7日金曜日
RFS netperf result
netperf benchmark result on lwn.net:
e1000e on 8 core Intel
   No RFS or RPS          104K tps at 30% CPU
   No RFS (best RPS config):    290K tps at 63% CPU
   RFS                    303K tps at 61% CPU
RPC test          tps     CPU%     50/90/99% usec latency     StdDev
   No RFS or RPS     103K     48%     757/900/3185          4472.35
   RPS only:          174K     73%     415/993/2468          491.66
   RFS               223K     73%     379/651/1382          315.61
13年6月7日金曜日
Accelerated RFS
• RFSをMultiQueue NICでも実現するため
のNICドライバ拡張
• Linux kernelはプロセスの実行中CPUを
NICドライバに通知
• NICドライバは通知を受けてフローのキ
ュー割り当てを更新
13年6月7日金曜日
Receive Side Scalingの制限
• 32bitのハッシュ値をそのまま使用して
いればハッシュ衝突しにくいが、
Indirection Tableが小さいので少ないビッ
ト数でindex値をマスクしている
→フローが多い時にハッシュ衝突する
• Accelerated RFSには不向き
13年6月7日金曜日
Flow Steering
• フローとキューの対応情報を記憶
4tuple:キュー番号のような形式で設定
• RSSのような明確な共通仕様は無いが、
各社の10GbEに実装されている
• Accelerated RFSはFlow Steeringを前提と
している
13年6月7日金曜日
Flow Steeringで
手動フィルタ設定
# ethtool --config-nfc ix00 flow-type tcp4
src-ip 10.0.0.1 dst-ip 10.0.0.2 src-port 10000
dst-port 10001 action 6
Added rule with ID 2045
13年6月7日金曜日
XPS
• MultiQueue NICは送信キューも複数持
っている
• XPSはCPUと送信キューの割り当てを決
めるインタフェース
13年6月7日金曜日
XPSの使い方
# echo 1 > /sys/class/net/eth0/queues/tx-0/xps_cpus
# echo 2 > /sys/class/net/eth0/queues/tx-1/xps_cpus
# echo 4 > /sys/class/net/eth0/queues/tx-2/xps_cpus
# echo 8 > /sys/class/net/eth0/queues/tx-3/xps_cpus
13年6月7日金曜日
4.データ移動に伴う
レイテンシの削減
13年6月7日金曜日
データ移動に伴う
レイテンシの削減
• プロトコル処理よりもむしろNIC メモ
リ CPUキャッシュの間でのデータ移
動に伴うオーバヘッドの方が重いケース
がある
• 特にメモリアクセスが低速
13年6月7日金曜日
Intel Data Direct I/O
Technology
• NICがDMAしたパケットのデータは、最初にCPU
がアクセスした時に必ずキャッシュヒットミスを
起こす
         ↓
• CPUのLLC(三次キャッシュ)にDMAしてしまえ!
• 新しいXeonとIntel 10GbEでサポート
• OS対応は不要(HWが透過的に提供する機能)
13年6月7日金曜日
コピーが重い
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年6月7日金曜日
コピーが重いが
ゼロコピー化は困難
• NICのDMAバッファはキュー毎に設定できるがフロ
ー毎ではない
→そもそもキューを一つのアプリで専有出来る前提
でないと無理
• バッファがページサイズにアライン・アロケートさ
れてないと無理
• パケットヘッダとペイロードが分離されてないとバ
ッファにパケットヘッダまで書かれてしまう
13年6月7日金曜日
• (Intel I/O ATとも呼ばれる)
• NICのバッファ→アプリケーションのバッフ
ァへDMA転送
• CPU負荷を削減
• チップセットに実装
• CONFIG_NET_DMA=y in Linux
Intel QuickData Technology
13年6月7日金曜日
5.プロトコルスタックを
経由しないネットワークIO
13年6月7日金曜日
プロトコルスタックを
経由しないネットワークIO
• プロトコル処理をする必要もSocket APIである必要も
無いなら、ネットワークIOはもっと速く出来る
• 特定用途向け
• プロトコル処理を必要としないアプリケーション
→snort、OpenvSwitchなど
• プロトコル処理を自前で行なってでも性能を上げ
たいアプリケーション
13年6月7日金曜日
基本的な仕組み
• 専用NICドライバと専用
ライブラリを用いて、
NICの受信バッファを
MMAP
• パケットをポーリング
• アプリ固有のパケット
に対する処理を実行NIC
RX1 RX2 RX3
Kernel Driver
App
RX1 RX2 RX3
MMAP
Pac
kets
Polling
Do some
work
13年6月7日金曜日
RAWソケット・BPF
との違い?
• ゼロコピーが基本
• マルチキューの受信バッファをそのままユーザ
ランドにエクスポートしている
• ↑により、マルチスレッド性能が高い
(RAWソケット・BPFはシングルスレッド)
• 上述の機能を実現するためNICのドライバを改造
13年6月7日金曜日
Intel DPDK
• 割り込みをやめてポーリングを使用しオーバヘッド削減
• 受信バッファにHugePageを使う事によりTLB missを低減
• 64 byte packetのL3フォワーディング性能(Intel資料より)
• Linux network stack:Xeon E5645 x 2 → 12.2Mpps
• DPDK:Xeon E5645 x 1 → 35.2Mpps
• DPDK : Next generation Intel Processor x 1 → 80Mpps
• OpenvSwitch対応
• 対応NIC:Intel
13年6月7日金曜日
類似の実装
• PF_RING DNA
ntopの実装、Linux向け
libpcapサポート
対応NIC:Intel
• Netmap
FreeBSD向けの実装、一応Linux版あり
libpcap, OpenvSwitchサポート
対応NIC:Intel, Realtek...
13年6月7日金曜日
まとめ
• 高速なネットワークIOを捌くために様々な改善が行
われている事を紹介
• ハードウェア・ソフトウェアの両面で実装の見直し
が要求されており、その範囲はネットワークに直接
関係ないような所にまで及ぶ
• 取り敢えず明日から出来ること:
まずはサーバに取り付けるNICを
「マルチキューNIC」「RSS対応」にしよう
13年6月7日金曜日

More Related Content

10GbE時代のネットワークI/O高速化