10gbe時代のネットワークi/o高速化

67
10GbE時代のネット ワークI/O高速化 Takuya ASADA<[email protected] > 1367日金曜日

Upload: takuya-asada

Post on 05-Dec-2014

22.126 views

Category:

Technology


9 download

DESCRIPTION

10GbE、40GbEなどの極めて高速な通信をサポートするNICが、PCサーバの領域でも使われるようになってきている。 このような速度の通信をソフトウェア(OS)で処理し高い性能を得るには様々な障害があり、ハードウェア・ソフトウェア両面の実装を見直す必要がある。 本セッションでは、ハードウェア・ソフトウェア両面にどのような改良が行われてきており、性能を引き出すにはどのようにこれらを使用したらよいのかについて紹介する。

TRANSCRIPT

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

Takuya ASADA<[email protected]>

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

inputqueue

socketqueue

パケット

システムコール

プロセス起床

ソフトウェア割り込みスケジュール

ハードウェア割り込み

ユーザ空間へコピー

13年6月7日金曜日

割り込みが多すぎる• NICの性能向上によって、一定時間に

NICが処理できるパケット数が飛躍的に増加

• 1パケット毎に割り込みが来ると、通信量が多いときにコンテキストスイッチ回数が増えすぎ性能が劣化

13年6月7日金曜日

旧来のパケット受信処理Process(User)

Process(Kernel)

HW Intr Handler

SW Intr Handler

パケット受信

プロトコル処理

ソケット受信処理

ユーザプログラム

user buffer

inputqueue

socketqueue

パケット

システムコール

プロセス起床

ソフトウェア割り込みスケジュール

ハードウェア割り込み

ユーザ空間へコピー

ハードウェア割り込み↓

受信キューにキューイング↓

ソフトウェア割り込みスケジュール

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

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込みスケジュール

パケット受信

パケットが無くなるまで繰り返し

ハードウェア割り込み↓

割り込み無効化&ポーリング開始

↓パケットが無くなったら割り込み有効化

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

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込みスケジュール

パケット受信

パケットが無くなるまで繰り返し

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

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込みスケジュール

パケット受信

パケットが無くなるまで繰り返し

cpu1

Process(User)

Process(Kernel)

HW Intr Handler

SW Intr Handler

割り込み無効化

プロトコル処理

ソケット受信処理

ユーザプログラム

user buffer

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込みスケジュール

パケット受信

パケットが無くなるまで繰り返し

13年6月7日金曜日

ソフト割り込みが1つのコアに偏る

13年6月7日金曜日

ソフト割り込みとは?Process(User)

Process(Kernel)

HW Intr Handler

SW Intr Handler

割り込み無効化

プロトコル処理

ソケット受信処理

ユーザプログラム

user buffer

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込みスケジュール

パケット受信

パケットが無くなるまで繰り返し

ポーリングからプロトコル処理まで→ネットワーク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 Reordering1 2 4 5 3 6

1 2 3 4 5 6

protocol processing

user buffer

reorderqueue

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

受信処理

割り込み

受信処理

■■

01

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

socketqueue

パケット

システムコール

プロセス起床

ハードウェア割り込み

ユーザ空間へコピー

パケットパケット

ソフトウェア割り込み

パケット受信

ハッシュ計算

ディスパッチ

プロトコル処理

ソケット受信処理

ユーザプログラム user

buffer

socketqueue

backlog#1

hash queue 参照■■

01

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 resultnetperf 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 resultnetperf 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

inputqueue

socketqueue

パケット

システムコール

プロセス起床

ソフトウェア割り込みスケジュール

ハードウェア割り込み

ユーザ空間へコピー

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

AppRX1 RX2 RX3

MMAP

Packets

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

• NetmapFreeBSD向けの実装、一応Linux版ありlibpcap, OpenvSwitchサポート対応NIC:Intel, Realtek...

13年6月7日金曜日

まとめ• 高速なネットワークIOを捌くために様々な改善が行われている事を紹介

• ハードウェア・ソフトウェアの両面で実装の見直しが要求されており、その範囲はネットワークに直接関係ないような所にまで及ぶ

• 取り敢えず明日から出来ること:まずはサーバに取り付けるNICを「マルチキューNIC」「RSS対応」にしよう

13年6月7日金曜日