Comments
Description
Transcript
事前資料
イマドキな ネットワークIO [email protected] はじめに • ネットワークの高速化に伴って ハード・ソフト両面でネットワークIOの実装 が繰り返し見直されてきている • これがLinuxカーネルの実装にも大きく影響し ている • 厳密にはルータではなくサーバの話だが Vyattaで用いられるPCルータにも大きく関係 旧来のパケット受信処理 user buffer ユーザ空間へコピー ユーザ プログラム システムコール Process(User) ソケット 受信処理 Process(Kernel) socket queue プロセス起床 プロトコル処理 input queue SW Intr Handler ソフトウェア割り込みスケジュール パケット受信 ハードウェア割り込み パケット HW Intr Handler ハードウェアの進化 • NIC性能の急激な向上 • • • NIC:1GbE→10GbE CPU:1GHz→3.2GHz・メモリ:CPUの1/10のペース マルチコアCPUの普及 • • 1CPUコアの性能を上げる→コア数を増やしていく ソフト・ハードの設計をマルチコア環境で性能が 出るように変えていく必要が出てきた 割り込みが多すぎる • NICの性能向上によって、一定時間に NICが処理できるパケット数が飛躍的に 増加 • 1パケット毎に割り込みが来ると、通 信量が多いときにコンテキストスイッ チ回数が増えすぎ性能が劣化 割り込みが多すぎる user buffer ユーザ空間へコピー ユーザ プログラム システムコール Process(User) ソケット 受信処理 Process(Kernel) socket queue プロセス起床 プロトコル処理 input queue SW Intr Handler ソフトウェア割り込みスケジュール パケット受信 ハードウェア割り込み パケット HW Intr Handler Interrupt Coalescing • ハードウェアでの対応 • パケット数個に一回割り込む、 或いは一定期間待ってから割り込む • 割り込みを間引く • デメリット:レイテンシが上がる ソフトウェアでの対応 • ポーリング • NICの割り込みを使わずに、タイマーを使って定期 的にNICのレジスタをポーリング、パケットが有っ たら受信処理 • ハイブリット方式 • 通信量が多く連続してパケット処理を行っている時 のみ割り込みを無効化、ポーリングで動作 →NAPI(Linux) 解説:http://tinyurl.com/LinuxNAPI NAPI user buffer ユーザ空間へコピー ユーザ プログラム システムコール Process(User) ソケット 受信処理 Process(Kernel) socket queue プロセス起床 プロトコル処理 パケットが無くなる まで繰り返し パケット受信 SW Intr Handler ソフトウェア割り込みスケジュール 割り込み無効化 ハードウェア割り込み パケット パケット パケット HW Intr Handler プロトコル処理が重い • 高速なNICを用いる環境では、ホストCPUで パケットを一つづつ処理する作業が大きな オーバヘッドになっている →CPUがボトルネック • 例:全二重な1Gbpsの通信を行うと、 Pentium4 2.4GHzでCPU時間を80%消費 • CPUをプロトコル処理から開放したい プロトコル処理が重い user buffer ユーザ空間へコピー ユーザ プログラム システムコール Process(User) ソケット 受信処理 Process(Kernel) socket queue プロセス起床 プロトコル処理 パケットが無くなる まで繰り返し パケット受信 SW Intr Handler ソフトウェア割り込みスケジュール 割り込み無効化 ハードウェア割り込み パケット パケット パケット HW Intr Handler TOE (TCP Offload Engine) • NICに実装されたTCP/IPスタックへプロトコル処理を フルオフロード • デメリット • セキュリティ:TOEにセキュリティホールが生じて も、OS側から対処が出来ない • 複雑性:OSのネットワークスタックをTOEで置き換 えるにはかなり広範囲の変更が必要であり、更に メーカによってTOEの実装が異なる TOE (TCP Offload Engine) • Linux:サポート予定無し • Windows:コネクションはOSで管理 解説:http://bit.ly/offload • 特定用途:RDMA, iSCSI HBA 部分的なオフロード • TCP Checksum Offload TCPのチェックサム計算 • Large Segment Offload 大きなパケット(例:64KB)をまとめて渡す と、NICでMTUに合わせて分割送信する • Large Receive Offload LSOの逆で、NIC上でパケットを結合し大きな パケットにしてカーネルに渡してくれる Linuxの対応状況 • TCP Checksum Offload 対応 TCPのチェックサム計算 • Large Segment Offload 大きなパケット(例:64KB)をまとめて渡す と、NICでMTUに合わせて分割送信する • ソフトウェアで実装 Large Receive Offload LSOの逆で、NIC上でパケットを結合し大きな パケットにしてカーネルに渡してくれる マルチコアが活用出来ない • マルチコア環境においても一つのNICの 受信処理は一つのCPUでしか行えてい ない • 通信量が多いときにパケット処理の負 荷が特定のコアへ大きく偏り性能に悪 影響を及ぼす 複数のCPUでパケット処理したい cpu0 user buffer ユーザ空間へコピー cpu1 ユーザ プログラム user buffer システムコール Process(User) ユーザ空間へコピー ソケット 受信処理 ユーザ プログラム システムコール ソケット 受信処理 Process(Kernel) socket queue プロトコル処理 Process(Kernel) socket queue プロセス起床 パケットが無くなる まで繰り返し パケット受信 Process(User) プロセス起床 プロトコル処理 パケットが無くなる まで繰り返し パケット受信 SW Intr Handler ソフトウェア割り込みスケジュール 割り込み無効化 SW Intr Handler ソフトウェア割り込みスケジュール 割り込み無効化 ハードウェア割り込み パケット パケット パケット ハードウェア割り込み パケット パケット パケット HW Intr Handler HW Intr Handler Receive Side Scaling • パケットヘッダのハッシュ値を元にパケットを 複数の受信キューへ振り分け • 受信キューはそれぞれのCPUコアに対応、 それぞれのCPUへ割り込む • • CPUごとに並列にパケット処理が行えるようになる 同一フローは一つのCPUへ振り分けられる →データローカリティを考慮 Receive Side Scaling cpu0 受信処理 cpu1 cpu2 cpu3 受信処理 割り込み RX Queue #0 RX Queue #1 RX Queue #2 ディスパッチ RX Queue #3 参照 hash ■ ■ queue 0 1 ハッシュ計算 パケット着信 パケット パケット パケット NIC Receive Side Scaling • MicrosoftがScalable Network Initiativeで提唱 解説:http://bit.ly/ReceiveSideScaling • • Windows・Linuxでサポート ハードウェア対応が必要 • • PCIバスのMSI-Xサポート NICへのRSS実装 RPS(Linux) • RSS非対応のオンボードNICをうまくつかってサー バの性能を向上させたい • • ソフトでRSSを実装してしまおう ソフト割り込みの段階でパケットを各CPUへばら まく • • CPU間割り込みを使って他のCPUを稼動させる RSSのソフトウエアによるエミュレーション cpu0 ユーザ プログラム user buffer ユーザ空間へコピー socket queue hash ■ ■ cpu1 ユーザ プログラム ソケット 受信処理 ディスパッチ ハッシュ計算 パケット受信 ソフトウェア割り込み 割り込み無効化 ハードウェア割り込み パケット パケット パケット user ソケット 受信処理 socket queue プロセス起床 queue 参照 0 1 cpu3 buffer システム コール プロトコル処理 cpu2 CPU間 割り込み プロトコル処理 backlog #1 backlog #2 backlog #3 RFS(Linux) • 受信待ちプロセスがいるCPUへパケッ トをディスパッチ出来る仕組みをRPSに 追加 • データローカリティの向上、レイテン シの削減 RPSのワーストケース CPU0 CPU1 CPU2 CPU3 プロセスB プロセス起床 ネットワーク スタック ポーリング 割り込みハンドラ デフォルトCPUへ割り込み NIC バッファ プロセス起床 プロセスがいるCPUへ転送 CPU0 CPU1 CPU2 CPU3 プロセスA プロセスB プロセス起床 プロセス起床 ネットワーク ネットワーク スタック ポーリング 割り込みハンドラ デフォルトCPUへ割り込み NIC バッファ スタック それでも遅い • • Intelの取り組み:http://bit.ly/IOATJ 何故、高速なNIC、CPU・最適化されたOSを使用している にも関わらずサーバのパフォーマンスは上がらないのか? • 最も深刻なボトルネックはCPUにネットワークI/O処理を 行わせていることが原因ではなく、データ移動に伴うオー バヘッドだった • メモリの速度はCPUよりはるかに低速であるため、メモリ アクセス時のメモリ・フェッチにはかなりの時間がかる TOEは要らない子 • TOEではごく かな性能改善しか出来ず、レイテン シの根本的な問題を解決していない • 何故、CPUより性能の低いオフロードエンジンが CPUよりも速いと考えられていたのか? →TCP/IPのデータ操作に最適化されている為 • 最適化されたTCP/IPスタックをCPU上に実装、 性能測定を行いTOEより高速化される事を確認 →オンロード Intel I/O Acceleration Technology • Intel QuickData Technology • Direct Cache Access • Receive Side Scaling • Large Receive Offload • Low Latency Interrupts +最適化されたネットワークスタック Intel QuickData Technology • NICのバッファ→アプリケーションの バッファへパケットをDMA転送 • CPU負荷を削減 • チップセットに実装、OSから利用 Intel QuickData Technology user buffer ユーザ空間へコピー ユーザ プログラム システムコール Process(User) ソケット 受信処理 Process(Kernel) socket queue プロセス起床 プロトコル処理 パケットが無くなる まで繰り返し パケット受信 SW Intr Handler ソフトウェア割り込みスケジュール 割り込み無効化 ハードウェア割り込み パケット パケット パケット HW Intr Handler Direct Cache Access • NICからメモリへDMA転送されたパケットを CPUからアクセスする時、キャッシュへ フェッチする為にレイテンシが発生している • • NICからキャッシュへ直接転送したい 難しいので、必ずprefetchが掛かるように ハードの実装を変更、フェッチコストを隠 DCA無し CPU Cache Snoop invalidate Fetch Writeback Memory Controller DMA Write I/O Device Memory Memory Wirte DCA有り CPU Cache Snoop invalidate +hint HW Prefetch Writeback Memory Controller DMA Write I/O Device Memory Memory Wirte 仮想化環境でも パフォーマンスを出したい • Intel VT-c • SR-IOV • 複数のゲストOSとNICを直接接続 • VMDq • VM間のIOスケジュール 従来の仮想ハードウェア VM1 フロントエンド ドライバ VM2 フロントエンド ドライバ Hypervisor バックエンド ドライバ デバイス ドライバ デバイス Intel VT-dによる PCI Passthrough VM1 VM2 デバイス ドライバ Hypervisor デバイス SR-IOV VM1 VFデバイス ドライバ VM2 VFデバイス ドライバ Hypervisor PFデバイス ドライバ 仮想 デバイス 仮想 デバイス デバイス VMDq VM1 VM2 VFデバイス ドライバ VFデバイス ドライバ Hypervisor PFデバイス ドライバ RX1 仮想 RX1 デバイス RX1 RX2 仮想 RX2 デバイス RX1 RX2 RX1 RX1 RX2 デバイス まとめ • ソフトウェア・ハードウェア双方で最適化を進 めないとならない • ある時点で正しかった答えがずっと正しいとは 限らない • 一つの解決策だけで問題が解消するとは限らな い • Intelがんばるなぁ