Blog

※本ブログの内容は個人的見解であり、所属組織及び企業の意見を代弁するものではありません。 / # The contents expressed here are only my personal opinions.

ストレージI/O高速化への取り組み:Linux BLK-MQ/SCSI-MQ

Linux関連のコア開発者から聞くところによると、ストレージのI/Oアーキテクチャはネットワークに比べ、10年くらい遅れていたらしい。長らくハードディスクという相当に遅いデバイスが相手だったので、それほど気にしなくても済んでいたという。

ところが、最近のフラッシュメモリ等々の急速な広まりで、ソフトウェア部分も強化が進んでいるようだ。1つの論理デバイスに対してCPUのマルチコアを活用するというネットワークでは今や当然となっている仕組みがストレージにもようやく搭載されつつある。Multi-Queue(マルチキュー)と呼ばれている。

Linuxの仕組みとしては、BLK-MQ(Multi-Queue)とSCSI-MQである。Linux以外のOSでは良く分からないが(きっとあると思います)、少なくともLinuxではシングル論理デバイス(LUN)当たり1M IOPS(100万IOPS)を実現すべく、搭載されつつある模様である。

[Phoronix] Blk-mq Is Almost Feature Complete & Fast With Linux 3.16

Merged for the Linux 3.13 kernel was the multi-queue block layer allows for better SSD performance with reduced latency and by balancing I/O workload across multiple CPU cores and supporting multiple hardware queues. With the upcoming Linux 3.16 kernel, the "blk-mq" code is expected to be feature complete and deliver great performance. 

Linux Kernel 3.13で実装されたマルチキューブロックレイヤにより、複数のハードウェアキューがサポートされ、複数のCPUコアにI/Oが分散されるようになり、より良いSSD性能とレイテンシー削減が実現された。Linux Kernel 3.16では、「BLK-MQ」コードが完成され、優れた性能が期待される。

 

[Phoronix] SCSI Multi-Queue Performance Appears Great For Linux 3.17

Building upon the major blk-mq work for the multi-queue block layer, the SCSI multi-queue code is now in good shape according to its developers, is delivering very promising performance results, and should be merged into the Linux 3.17 kernel cycle. 

 マルチキューブロックレイヤに関するBLK-MQの取り組みに関して、開発者によると、SCSIマルチキューのコードは、良い状況となっており、非常に良い性能値が実現され、Linux Kernel 3.17サイクルにマージされるようだ。

 

 In terms of the performance potential of this new code to better take advantage of multiple CPU cores and designed to work with (eventually) multiple hardware queues too, "The usage of blk-mq dramatically decreases CPU usage under all workloads going down from 100% CPU usage that the old setup can hit easily to usually less than 20% for maxing out storage subsystems with 512byte reads and writes, and it allows to easily archive millions of IOPS." 

複数のCPUコアと複数のハードウェアキューを活用する新しいコードの期待性能に関しては、「BLK-MQの活用は、全てのワークロード下でCPU使用率を劇的に減少させ、従来のコードでCPU使用率100%であったものを20%以下にし、ストレージサブシステムの512バイトのリード及びライト性能を最大化し、100万IOPS(1M IOPS)を容易に実現させる」

 

 

VXLANオフロード性能

Mellanoxコミュニティというのがあり、英語ではありますが、誰でも登録すると技術的な質問をすることができます。是非ご活用ください。

 

最近の投稿から1つ。

http://community.mellanox.com/thread/1692

 I'm testing out ConnectX-3 Pro with VXLAN Offload in our lab. Using a single-stream iperf performance test, we get ~34Gbit/s transfer speed of non-VXLAN transport, but only ~28Gbit/s with VXLAN encapsulation.

(省略)

We're certainly happy with 28Gbit/s, but I'm wondering if there are plans to improve this to the point that VXLAN adds no additional CPU overhead at all, or if there is any tuning I can do towards the same goal?

(日本語訳(若干意訳):早く読めると思うので)

ConnectX-3 Proという VXLANオフロードができるNIC(訳者注:40GbE NICです)をラボでテストしてる。シングルストリームのiperfの性能テストで、VXLAN使わないと34Gbpsくらいの速度だが、VXLAN使うと(訳者注:NICオフロードで)28Gbpsくらい。

(省略)

28Gbpsでもまあ、満足だが、CPUオーバーヘッドをゼロにしてもっと速くできないの?

 

この方の例ですと、シングルストリームで34Gbps、VXLAN使ってもオフロードで28Gbpsとのことです。シングルストリームでの性能なら、かなり速いと思いますが。飽くなき追求ですね。

スレッドでは丁寧にコメントも付いているので参考になると思います。

 

IPoIB(IP over InfiniBand)関連の話題

IPoIB(IP over InfiniBand)は、InfiniBand上でIPプロトコルを動作させるプロトコルである。

f:id:kz_tomo:20140601215530j:plain

フレームフォーマットとしては、InfiniBandフレームでIPフレームをカプセル化するため、IPoIBヘッダが存在する。

WireSharkでのキャプチャ例

InfiniBandパケットはibdumpというコマンドでダンプでき、WireSharkで表示することができる。下記はIPoIBのパケットを表示した例である。

上述のIPoIBフレームでのInfiniBandヘッダ、IPoIBヘッダ、IPヘッダ、TCPヘッダが確認できる。

f:id:kz_tomo:20140601220227j:plain

IPoIBにはEthernetヘッダ(MACヘッダ)が存在しないが、EthernetヘッダもInfiniBandでカプセル化したEoIBというプロトコルも存在する。

また、IPoIBフレームのIPoIBヘッダをホスト側の中間ドライバでEthernetヘッダに付け替えることにより、ソフトウェアからはEthernetデバイスとしての処理を可能とするeIPoIBという方式もある。eIPoIBは、ネットワークを流れるプロトコルはあくまでIPoIBである。

EoIBとeIPoIBについては、別途今後の記事にて説明を行いたいと考えている(ここでは省略)。

Connected modeとDatagram mode

IPoIBには、Connected modeとDatagram modeが存在する。Connected mode(CM)は、RC(Reliable Connected)というInfiniBandの通信形態を使用し、Datagram modeは、UD(Unreliable Datagram)というInfiniBandの通信形態を使用する。RC通信は、通信ペア毎にメモリ上にリソースを確保(Connected)し、通信ロスを検出する(ロスレス)プロトコルである。一方、UD通信は、通信に関するメモリリソースを確保することなく(Datagram)、通信ロスは検出できない(※TCPUDPの関係に似ている。UDPであっても、上位ソフトウェアで通信管理することでロスレス通信が可能である。ロスのある通信プロトコルだから信頼性がないと考えるのは正しくない。)

また、IPoIB CMでは、Connected通信を行うことで、MTUを最大64KBとすることができる。ただし、ここでのMTUは、IPoIBとしてのMTUであり、InfiniBand通信のMTUはInfiniBand規格での最大4KBである点は変わらない点には注意が必要である。実際にMTU=64KBのInfiniBandフレームがネットワークを流れることはない。(したがって、InfiniBandスイッチのMTUとの整合性についても問題ない。)

f:id:kz_tomo:20140601223228j:plain

Connected modeでのIPoIB通信キャプチャ例。IPoIBとしてのMTUは大きいが、InfiniBandネットワーク上では最大4KBでのフレームに分割されている。上図のWireSharkキャプチャにおいて、枠で囲った部分がIPoIBパケットに組み立てられる際にMTU=64KB等の大きなサイズになる。

 

最新状況:Datagramモードの方が性能が良い

長らくConnectedモードの方が性能が出る状況が続いていたが、最近の状況を補足しておく。

MellanoxのLinuxドライバであるMLNX OFEDでは、従来のMLNX OFED 1.x系とMLNX OFED 2.x系(2013年4月~)以降ではIPoIBドライバの設計が見直されており、従来の1.x系ではMTUの大きいConnectedモードの方が性能が良かったが、2.x系以降、IPoIB通信の性能は、1.x系でのIPoIB性能を上回ると共に、同じ2.x系で比較した場合、Datagramモードの方が性能が出る作りとなっているようだ。詳しい性能値は省略するが、InfiniBandの帯域を充分に活用できるスループット値が出るレベルになっていると考えてよい。従来、IPoIBは汎用性が高いものの性能面で課題があると言われていたが、最新状況ではスループット的にも実用性が増してきている。

スループット的には相当レベルに到達はしているが、RDMA系ドライバとの差異は、CPU使用率レイテンシーといったカーネルバイパス、CPUゼロコピーの点で依然として存在する。

  • MLNX OFED IPoIB性能状況 : 1.x系IPoIB-UD < 1.x系IPoIB-CM < 2.x系IPoIB-CM < 2.x系IPoIB-UD

また、MLNX OFEDをインストールした際のデフォルト設定は、1.x系ではConnectedモードであったが、2.x系ではDatagramモードとなっている。一般には、性能面からもデフォルトのDatagram modeのまま使用するのが推奨である。

(2014/6/7追記)現時点での最新ドライバMLNX OFED 2.2-1.0.1でのデフォルト設定は、Datagram mode, MTU=2044となっている。

例外として、Connect-IBという最新のHCAでは本稿執筆時点のMLNX OFED 2.2-1.0.1ではデフォルトはConnectedモードとなっている。 

 

以上、IPoIBの方式と最近の状況について説明した。本ブログ筆者は元々、長年ストレージ関連の開発に従事し、ファイバチャネルドライバやiSCSIドライバの開発も長らく務めていたため、プロトコル周辺の話題については非常に親しみがある。今後も重点的に取り上げていきたいと考えている。

 

NUMAアーキテクチャとネットワーク性能(2)-実践編

前回、NUMAアーキテクチャがネットワーク性能に与える影響についての技術的な背景を説明した。

(前回記事)

NUMAアーキテクチャとネットワーク性能(1)-説明編 - Interconnect Your Future - InfiniBand and RoCE

本稿では、実際にLinux環境でネットワーク性能を測定し、NUMAが与える影響についての事例とノウハウを紹介したい。

本稿では、最終的には下記測定例をまとめている。NUMA構成が異なる場合、性能が全く異なってしまう。極端な話、40GbE NICなのに4-5Gbpsしか出ないことになってしまう。実際には性能出ます。注意。

  • NUMA構成上遠い構成でのiperf性能:1プロセス(1コア) 2.00Gbps、12プロセス(6コア) 4.84Gbps
  • NUMA構成上近い構成でのiperf性能:1プロセス(1コア) 14.7Gbps、12プロセス(6コア) 37.9Gbps

 ※現在のサーバアーキテクチャ上の仕様であるため、NICとかドライバの話ではないことに注意。チューニングを自動化して使いやすくするという話はあり、実際に自動チューニングソリューションが存在する(本稿最後に記載)。

NUMA構成の確認方法

理想的にはNUMA構成上、NICが接続されているPCI Expressバスが直結されているCPUでアプリケーションを実行する必要がある。

NICが接続されているNUMAノードの確認方法

下記の例のように確認できる。

確認例:eth2の場合

# cat /sys/class/net/eth2/device/numa_node

本実行例では、eth2というNICは、NUMAノード1に接続されている。

 

NUMAノードに所属するCPUコア番号の確認方法

下記の例のように確認できる。

# cat /sys/devices/system/node/node1/cpulist

 6-11

本実行例では、NUMAノード1に所属するCPUコア番号(6~11)が得られている。

参考:同一環境でnode0のCPUコア番号を求めた例は下記である。

# cat /sys/devices/system/node/node0/cpulist

0-5

実行CPU指定方法

# taskset -c [CPU番号(複数指定する場合、カンマ(,)区切りまたはハイフン(-)指定)] [実行コマンド]

例1:# taskset -c 0,1,2 iperf -s

例2:# taskset -c 0-5 iperf -s

参考:(RedHatサポートサイト) 第6章 親和性

ネットワーク性能測定方法

上記により、本実行例では、eth2に関するネットワーク性能測定では、eth2が接続されているNUMAノード1に所属するCPUコア6~11でベンチマークソフトウェアを動作させる必要があることになる。

  • eth2が所属するNUMAノード=1
  • NUMAノード=1に所属するCPUコア番号=6~11

実機測定例

今回性能測定に使用したNICと測定環境

  • Mellanox ConnectX-3Pro Dual Port(40GbE) [FW:2.31.5050]
  • OS : Ubuntu 14.04 Server
  • ドライバ:MLNX OFED 2.2-1.0.1
  • 接続構成:Mellanox SX1012(12ポート40GbEスイッチ)経由で2台の同一サーバを接続
  • 送信側サーバIPアドレス:12.0.0.1
  • 受信側サーバIPアドレス:12.0.0.2
  • MTU : Default (1500 byte)

$ ifconfig eth2

eth2      Link encap:Ethernet  HWaddr (-----snip----) 

          inet addr:12.0.0.1  Bcast:12.0.0.255  Mask:255.255.255.0

          inet6 addr: fe80::f452:1400:17a:5532/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:3519272 errors:0 dropped:1 overruns:0 frame:0

          TX packets:113091827 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:226370515 (226.3 MB)  TX bytes:171670950196 (171.6 GB)

# ethtool -i eth2

driver: mlx4_en

version: 2.2-1.0.0 (May 11 2014)

firmware-version: 2.31.5050

bus-info: 0000:82:00.0

supports-statistics: yes

supports-test: yes

supports-eeprom-access: no

supports-register-dump: no

supports-priv-flags: yes

# ethtool eth2

Settings for eth2:

Supported ports: [ TP ]

Supported link modes:   1000baseT/Full 

                       1000baseKX/Full 

                       10000baseT/Full 

                       10000baseKX4/Full 

                       10000baseKR/Full 

                       40000baseKR4/Full 

                       40000baseCR4/Full 

                       40000baseSR4/Full 

                       40000baseLR4/Full 

Supported pause frame use: No

Supports auto-negotiation: No

Advertised link modes:  1000baseT/Full 

                       1000baseKX/Full 

                       10000baseT/Full 

                       10000baseKX4/Full 

                       10000baseKR/Full 

                       40000baseKR4/Full 

                       40000baseCR4/Full 

                       40000baseSR4/Full 

                       40000baseLR4/Full 

Advertised pause frame use: No

Advertised auto-negotiation: No

Speed: 40000Mb/s

Duplex: Full

Port: Twisted Pair

PHYAD: 0

Transceiver: internal

Auto-negotiation: off

MDI-X: Unknown

Supports Wake-on: d

Wake-on: d

Current message level: 0x00000014 (20)

      link ifdown

Link detected: yes

# ibstat

CA 'mlx4_0'

CA type: MT4103

Number of ports: 2

Firmware version: 2.31.5050

Hardware version: 0

Node GUID: 0xf4521403xxxxxx

System image GUID: 0xf452140300xxxxxx

Port 1:

State: Down

Physical state: Disabled

Rate: 10

Base lid: 0

LMC: 0

SM lid: 0

Capability mask: 0x00010000

Port GUID: 0xf65214fffexxxxxx

Link layer: Ethernet

Port 2:

State: Active

Physical state: LinkUp

Rate: 40

Base lid: 0

LMC: 0

SM lid: 0

Capability mask: 0x00010000

Port GUID: 0xf452140001xxxxxx

Link layer: Ethernet

$ iperf -v

iperf version 2.0.5 (08 Jul 2010) pthreads

 測定結果(1プロセス、1CPUコア使用)

NICから遠いNUMAノードであるNUMA=0に所属するCPUコア=0で1プロセスを実行

iperf server(受信側) :

# taskset -c 0 iperf -s // CPU=0はNUMA=0に所属(eth2から遠いNUMAノード)

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 85.3 KByte (default)

------------------------------------------------------------

[  4] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42358

[ ID] Interval       Transfer     Bandwidth

[  4]  0.0-10.0 sec  2.33 GBytes  2.00 Gbits/sec

 iperf client(送信側):

# taskset -c 0 iperf -c 12.0.0.2 -P 1  // CPU=0はNUMA=0に所属(eth2から遠いNUMAノード)

------------------------------------------------------------

Client connecting to 12.0.0.2, TCP port 5001

TCP window size: 1.06 MByte (default)

------------------------------------------------------------

[  3] local 12.0.0.1 port 42358 connected with 12.0.0.2 port 5001

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-10.0 sec  2.33 GBytes  2.00 Gbits/sec

 

NICから近いNUMAノードであるNUMA=1に所属するCPUコア=6で1プロセスを実行

 iperf server(受信側) :

# taskset -c 6 iperf -s // CPU=6はNUMA=1に所属(eth2から近いNUMAノード)

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 85.3 KByte (default)

------------------------------------------------------------

[  4] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42362

[ ID] Interval       Transfer     Bandwidth

[  4]  0.0-10.0 sec  17.1 GBytes  14.7 Gbits/sec

 iperf client(送信側):

# taskset -c 6 iperf -c 12.0.0.2 -P 1 // CPU=6はNUMA=1に所属(eth2から近いNUMAノード)

------------------------------------------------------------

Client connecting to 12.0.0.2, TCP port 5001

TCP window size: 1.06 MByte (default)

------------------------------------------------------------

[  3] local 12.0.0.1 port 42362 connected with 12.0.0.2 port 5001

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-10.0 sec  17.1 GBytes  14.7 Gbits/sec

測定結果(12プロセス、6CPUコア使用)

NICから遠いNUMAノードであるNUMA=0に所属するCPUコア=0~5で12プロセスを実行

iperf server(受信側) :

# taskset -c 0-5 iperf -s // CPU=0~5はNUMA=0に所属(eth2から遠いNUMAノード)

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 85.3 KByte (default)

------------------------------------------------------------

[ 16] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42446

[  4] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42447

[  5] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42448

[  6] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42450

[  7] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42449

[  8] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42451

[  9] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42452

[ 10] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42453

[ 11] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42454

[ 12] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42455

[ 13] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42456

[ 14] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42457

[ ID] Interval       Transfer     Bandwidth

[ 10]  0.0-10.0 sec   378 MBytes   316 Mbits/sec

[  6]  0.0-10.0 sec   297 MBytes   249 Mbits/sec

[  7]  0.0-10.0 sec   564 MBytes   472 Mbits/sec

[  8]  0.0-10.0 sec   457 MBytes   383 Mbits/sec

[ 12]  0.0-10.0 sec   418 MBytes   350 Mbits/sec

[  9]  0.0-10.1 sec   451 MBytes   375 Mbits/sec

[ 16]  0.0-10.1 sec   348 MBytes   289 Mbits/sec

[ 11]  0.0-10.1 sec   872 MBytes   722 Mbits/sec

[ 14]  0.0-10.1 sec   492 MBytes   407 Mbits/sec

[  5]  0.0-10.2 sec   384 MBytes   316 Mbits/sec

[  4]  0.0-10.2 sec   480 MBytes   393 Mbits/sec

[ 13]  0.0-10.2 sec   772 MBytes   632 Mbits/sec

[SUM]  0.0-10.2 sec  5.78 GBytes  4.84 Gbits/sec

 iperf client(送信側):

# taskset -c 0-5 iperf -c 12.0.0.2 -P 12  // CPU=0~5はNUMA=0に所属(eth2から遠いNUMAノード)

------------------------------------------------------------

Client connecting to 12.0.0.2, TCP port 5001

TCP window size: 1.06 MByte (default)

------------------------------------------------------------

[ 14] local 12.0.0.1 port 42457 connected with 12.0.0.2 port 5001

[  4] local 12.0.0.1 port 42447 connected with 12.0.0.2 port 5001

[  3] local 12.0.0.1 port 42446 connected with 12.0.0.2 port 5001

[  5] local 12.0.0.1 port 42448 connected with 12.0.0.2 port 5001

[  6] local 12.0.0.1 port 42449 connected with 12.0.0.2 port 5001

[  7] local 12.0.0.1 port 42450 connected with 12.0.0.2 port 5001

[  8] local 12.0.0.1 port 42451 connected with 12.0.0.2 port 5001

[  9] local 12.0.0.1 port 42452 connected with 12.0.0.2 port 5001

[ 10] local 12.0.0.1 port 42453 connected with 12.0.0.2 port 5001

[ 11] local 12.0.0.1 port 42454 connected with 12.0.0.2 port 5001

[ 12] local 12.0.0.1 port 42455 connected with 12.0.0.2 port 5001

[ 13] local 12.0.0.1 port 42456 connected with 12.0.0.2 port 5001

[ ID] Interval       Transfer     Bandwidth

[  6]  0.0-10.0 sec   564 MBytes   473 Mbits/sec

[  7]  0.0-10.0 sec   297 MBytes   249 Mbits/sec

[ 10]  0.0-10.0 sec   378 MBytes   317 Mbits/sec

[ 12]  0.0-10.0 sec   418 MBytes   351 Mbits/sec

[  8]  0.0-10.0 sec   457 MBytes   383 Mbits/sec

[  3]  0.0-10.1 sec   348 MBytes   289 Mbits/sec

[  9]  0.0-10.1 sec   451 MBytes   375 Mbits/sec

[ 14]  0.0-10.1 sec   492 MBytes   407 Mbits/sec

[ 11]  0.0-10.1 sec   872 MBytes   723 Mbits/sec

[  5]  0.0-10.2 sec   384 MBytes   316 Mbits/sec

[  4]  0.0-10.2 sec   480 MBytes   394 Mbits/sec

[ 13]  0.0-10.2 sec   772 MBytes   633 Mbits/sec

[SUM]  0.0-10.2 sec  5.78 GBytes  4.85 Gbits/sec

 

NICから近いNUMAノードであるNUMA=1に所属するCPUコア=6~11で12プロセスを実行

 iperf server(受信側) :

# taskset -c 6-11 iperf -s // CPU=6~11はNUMA=1に所属(eth2から近いNUMAノード)

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 85.3 KByte (default)

[ 16] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42506

[  4] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42507

[  5] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42508

[  6] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42509

[  7] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42510

[  9] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42513

[  8] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42511

[ 10] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42514

[ 11] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42512

[ 12] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42515

[ 13] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42516

[ 14] local 12.0.0.2 port 5001 connected with 12.0.0.1 port 42517

[ ID] Interval       Transfer     Bandwidth

[ 16]  0.0-10.0 sec  2.65 GBytes  2.28 Gbits/sec

[  4]  0.0-10.0 sec  4.09 GBytes  3.51 Gbits/sec

[  7]  0.0-10.0 sec  5.51 GBytes  4.73 Gbits/sec

[  8]  0.0-10.0 sec  2.77 GBytes  2.37 Gbits/sec

[ 12]  0.0-10.0 sec  2.80 GBytes  2.40 Gbits/sec

[ 13]  0.0-10.0 sec  2.60 GBytes  2.23 Gbits/sec

[  5]  0.0-10.0 sec  4.10 GBytes  3.52 Gbits/sec

[  6]  0.0-10.0 sec  2.34 GBytes  2.01 Gbits/sec

[  9]  0.0-10.0 sec  2.96 GBytes  2.54 Gbits/sec

[ 10]  0.0-10.0 sec  5.37 GBytes  4.60 Gbits/sec

[ 11]  0.0-10.0 sec  4.23 GBytes  3.62 Gbits/sec

[ 14]  0.0-10.0 sec  4.74 GBytes  4.06 Gbits/sec

[SUM]  0.0-10.0 sec  44.2 GBytes  37.9 Gbits/sec

 iperf client(送信側):

# taskset -c 6-11 iperf -c 12.0.0.2 -P 12 // CPU=6~11はNUMA=1に所属(eth2から近いNUMAノード)

------------------------------------------------------------

Client connecting to 12.0.0.2, TCP port 5001

TCP window size: 1.06 MByte (default)

------------------------------------------------------------

[ 14] local 12.0.0.1 port 42517 connected with 12.0.0.2 port 5001

[  6] local 12.0.0.1 port 42508 connected with 12.0.0.2 port 5001

[  4] local 12.0.0.1 port 42506 connected with 12.0.0.2 port 5001

[  3] local 12.0.0.1 port 42507 connected with 12.0.0.2 port 5001

[  7] local 12.0.0.1 port 42509 connected with 12.0.0.2 port 5001

[  5] local 12.0.0.1 port 42510 connected with 12.0.0.2 port 5001

[  8] local 12.0.0.1 port 42511 connected with 12.0.0.2 port 5001

[  9] local 12.0.0.1 port 42513 connected with 12.0.0.2 port 5001

[ 10] local 12.0.0.1 port 42512 connected with 12.0.0.2 port 5001

[ 11] local 12.0.0.1 port 42514 connected with 12.0.0.2 port 5001

[ 12] local 12.0.0.1 port 42515 connected with 12.0.0.2 port 5001

[ 13] local 12.0.0.1 port 42516 connected with 12.0.0.2 port 5001

[ ID] Interval       Transfer     Bandwidth

[  6]  0.0-10.0 sec  4.10 GBytes  3.52 Gbits/sec

[  4]  0.0-10.0 sec  2.65 GBytes  2.28 Gbits/sec

[  3]  0.0-10.0 sec  4.09 GBytes  3.52 Gbits/sec

[  7]  0.0-10.0 sec  2.34 GBytes  2.01 Gbits/sec

[  5]  0.0-10.0 sec  5.51 GBytes  4.74 Gbits/sec

[  8]  0.0-10.0 sec  2.77 GBytes  2.38 Gbits/sec

[  9]  0.0-10.0 sec  2.96 GBytes  2.54 Gbits/sec

[ 12]  0.0-10.0 sec  2.80 GBytes  2.41 Gbits/sec

[ 13]  0.0-10.0 sec  2.60 GBytes  2.24 Gbits/sec

[ 14]  0.0-10.0 sec  4.74 GBytes  4.06 Gbits/sec

[ 10]  0.0-10.0 sec  4.23 GBytes  3.63 Gbits/sec

[ 11]  0.0-10.0 sec  5.37 GBytes  4.60 Gbits/sec

[SUM]  0.0-10.0 sec  44.2 GBytes  37.9 Gbits/sec

まとめ

  • NUMA構成上遠い構成でのiperf性能:1プロセス(1コア) 2.00Gbps、12プロセス(6コア) 4.84Gbps
  • NUMA構成上近い構成でのiperf性能:1プロセス(1コア) 14.7Gbps、12プロセス(6コア) 37.9Gbps

本測定例からも分かるように、NUMA構成の設定(アフィニティ(Affinity)設定)は非常に重要である。性能的に不利な構成で性能測定を行うと、本例のような極端な構成では、40GbE NICなのに4-5Gbpsしか性能が出ないといったことも起こりうる。

 

補足

Mellanoxでは、NUMAアフィニティ設定を自動で実行するコマンドを用意している。

# mlnx_affinity start

と実行すれば、コマンドが自動的にNUMAアフィニティ設定を実行する(ワンタイムでの実行で、プロセスは設定後に終了する)。

実行例:

# mlnx_affinity start

INFO - This utility does not support irqbalance control in Ubuntu 14.04 LTS \n \l

INFO - irqbalance status will not change

 

mlnx_affinity started[  OK  ]

また、MLNX OFEDを使用している場合は、設定ファイル(/etc/infiniband/obenib.conf/openib.conf)内の下記パラメータを設定することにより、アフィニティはサーバ起動時に自動設定されるようになる。

/etc/infiniband/obenib.conf/openib.conf

# Run /usr/sbin/mlnx_affinity

 RUN_AFFINITY_TUNER=yes // no-->yesに変更

 

本内容を含む性能チューニングガイドが下記で公開されている。

http://www.mellanox.com/related-docs/prod_software/Performance_Tuning_Guide_for_Mellanox_Network_Adapters.pdf

続きを読む

NUMAアーキテクチャとネットワーク性能(1)-説明編

NUMA(Non-Uniform Memory Access)とは

Non-uniform memory access - Wikipedia, the free encyclopedia

NUMA - Wikipedia

NUMA(Non-Uniform Memory Access、ヌマ)とは、共有メモリ型マルチプロセッサコンピュータシステムのアーキテクチャのひとつで、複数プロセッサが共有するメインメモリへのアクセスコストが、メモリ領域とプロセッサに依存して均一でないアーキテクチャである。

複数CPUがある場合、近いメモリと遠いメモリが構成上存在し、データが置かれる場所によって、性能に差が出てしまうアーキテクチャである。

 

 ネットワーク性能を測定する場合も、NUMA構成上不利な状態で性能測定をしてしまうと、思うような性能が出ない場合があるため、注意が必要である。本稿では、NUMA及びCPU構成の概要とネットワーク性能についてを述べる。

 

Intelサーバーの場合、Nehalem世代からNUMAが導入された。

参考:

Nehalem世代のアーキテクチャ | データセンター完全ガイド

 

ASCII.jp:インテルCPUの大きな転換点に立つNehalem (2/3)

CPUにメモリーコントローラーが内蔵されるということは、複数のCPUを搭載するシステムでは、それぞれのCPUごとにメモリーが搭載されることになる。つまり、メモリーアーキテクチャーがNUMA(ヌーマ、Non Uniform Memory Access)になる。なお、米AMD社のOpteronもNUMAアーキテクチャーを採用している。

NUMAに関する細かな説明は省くが、CPUごとにメインメモリーが分かれるため、OSはそれぞれのCPUに属するメモリーを参照する必要が出てくる。

 Intel Nehalem世代サーバー(2009年頃~):

  • CPUにメモリコントローラを内蔵
  • I/Oはサウスブリッジ経由

f:id:kz_tomo:20140525221349j:plain

従来、CPUからメモリへアクセスする場合は、CPUが接続されているノースブリッジと呼ばれるチップセットを経由していたため、CPUから直接メモリアクセスできるようになった点が大きなアップデートであった。

 

Intel SandyBridge世代からは、I/OコントローラもCPUに内蔵された。

参考:

 2011年 Intelサーバー向けプロセッサのロードマップ | データセンター完全ガイド

 

Intel SandyBridge世代以降のサーバー(2012年頃~):

  • CPUにメモリコントローラとI/Oコントローラを内蔵

f:id:kz_tomo:20140525221500p:plain

 要するにI/Oパスに関わるコンポーネントは全部CPUに統合された。

 

ネットワーク性能に関する考察

さて、本題のネットワーク性能についてだが、ネットワーク通信では送信側サーバは、メモリからNIC、受信側サーバは、NICからメモリへデータが流れることになる。

※実際には、データ転送処理でCPUコピーが発生する場合には、CPUレジスタへのロードが必要となるため、メモリ/CPU間のデータ転送が発生する。DMA転送で処理される場合にはデータはCPUを経由しない(RDMA含む)。

 

上述の通り、現在のサーバアーキテクチャでは、NICが接続されるPCI ExpressバスはCPUから直接出ており、メモリもCPU直結であるため、理想的にはネットワーク通信に関わるNICとメモリは同じCPUで完結すべきである。

 

DellのNUMAに関するホワイトペーパー(PDF)

NUMA Best Practices for Dell PowerEdge 12th Generation Servers - Dell TechCenter - TechCenter - Dell Community

上記Dellホワイトペーパーでは、NUMAノードの近いメモリと遠いメモリでどの程度の性能差が発生するかについて、測定例が示されている。

 

f:id:kz_tomo:20140525230041j:plain

 NUMAノードの近いメモリに対して、遠いメモリは半分のバンド幅しか性能が出ていない。

 

f:id:kz_tomo:20140525230320j:plain

 レイテンシー(処理完了時間)についても、遠いメモリは近いメモリより約60%も時間が掛かってしまう。

 

以上、NUMA構成とネットワーク性能についての関連事項と性能傾向について説明した。次回は、実際にLinux環境でネットワーク性能を測定し、NUMA構成の与える影響と設定方法について紹介する。

NUMAアーキテクチャとネットワーク性能(2)-実践編 - Interconnect Your Future - InfiniBand and RoCE

 

Mellanox Windowsドライバ WinOF4.70でのアップデート

日本ではゴールデンウィークの最中でしたが、日本時間2014年5月5日の深夜に下記WEBにてさりげなくリリースとなっています。

Mellanox Products: Mellanox OFED for Windows (WinOF)

 

下記に概要とトピックを説明します。

 

MellanoxのWindowsドライバは、VPI(Virtual Protocol Interconnect)版ドライバです。

(InfiniBandとEthernetの両方をサポートするドライバ)

 

Mellanox WinOF Rev 4.70 New Features(リリースノートから抜粋)

 

  • Ethernet SR-IOV over Windows Hyper-V Hypervisor (over Windows 2012 R2)1
  • Virtual Ethernet Adapter support (over Windows 2012 and above)2
  • RoCEv2: RoCE over Layer 3 networks (only for ConnectXR-3 Pro)
  • Lossless TCP buffer management when no receive WQE are available
  • IPoIB SR-IOV over KVM Hypervisor (Beta level)

 

 今回のリリースでは大きなアップデートが2点あります。

 

1.RoCEv2のサポート

RoCE Version 2という新しいプロトコルがサポートされました。

元々RoCEは、InfiniBandフレームの最下位ヘッダをEthernetヘッダに置き換えただけのものであったため、IPヘッダが存在せず、IPルーティングが出来ないという制約がありました(参考:当ブログ過去記事)。EthernetベースでのRDMAプロトコルであるRoCEでL3でのスケーリングが出来ればさらに大規模で柔軟なシステム構成が可能となるため、RoCEのL3対応は長らく課題とされていました。

RoCEv2は、そのような課題を解消し、理想的なプロトコルを実現するものであり、L3活用でのオーバーレイネットワークの方向性と合わせて投入された新世代のプロトコルであると言えます。

 

プロトコルは非常に新しいため、今後随時情報アップデートを行っていきたいと思います。

今後色々なシステムで検証が実施されていくのが楽しみです。

 

参考:例外的に既に使用しているユーザーも存在します。当ブログの過去エントリ、

http://rdma.hatenablog.com/entry/2014/04/28/212936

で紹介したスライドをよく見るとはっきりと書いてあります。

 

2.Virtual Ethernet Adapterのサポート(vea_manコマンド)

詳しくはドライバユーザーマニュアル「8.11 Virtual Ethernet Adapter」の章を参照。

このコマンド(vea_manコマンド)を使用すると、1つの10/40GbE物理ポートを2つの論理ポートとしてWindows OSへ提供できます。

従来より同様のコマンドはInfiniBand向けにはサポートされていました(part_manコマンド)が、Ethernetでは未サポートでした。

WinOF4.70では、Ethernetでもサポートという点がアップデートです。

 

なぜ論理ポート追加コマンドが必要か

 

理由:SMB Direct(RDMA)と仮想スイッチ経由のアクセスを同一物理ポートで共存させるため(I/O統合(Unified I/O)の実現)

 

http://technet.microsoft.com/ja-jp/library/jj134210.aspx

SMB ダイレクトを使用する場合の考慮事項 より抜粋(※Windowsの仕様です)

  • Hyper-V 管理オペレーティング システムで SMB ダイレクトを使用して、Hyper-V over SMB を使用できるようにしたり、Hyper-V 記憶域スタックを使用する仮想マシンに記憶域を提供したりできます。ただし、RDMA 対応ネットワーク アダプターは Hyper-V クライアントに直接公開されません。RDMA 対応ネットワーク アダプターを仮想スイッチに接続すると、そのスイッチからの仮想ネットワーク アダプターは RDMA 対応ではなくなります。

part_manコマンド(InfiniBand)、vea_manコマンド(Ethernet)を使って1つの物理ポートを2つの論理ポートとしてWindowsへ提供することで、上記制約事項をクリアし、RDMAと仮想スイッチの両立を実現できます。

 

# 本件については別エントリとして記事作成を予定しています。

 

Microsoft Azureでの40GbE RoCE (RDMA over Converged Ethernet)活用

Microsoft Azure

Microsoft Azureといえば、InfiniBandで動くHPCクラウドが2012年11月のSC12にてスパコンTOP500にランクイン(165位)し、2013年11月時点では、TOP500の309位にランキングされている。

Windows Azure Benchmarks Show Top Performance for Big Compute

TOP500 site : http://www.top500.org/site/50454

一方、表題のMicrosoft Azureでの40ギガビットイーサネットベースでのRDMA(RoCE)活用は、HPCクラウドではなく、より広く使われている一般的なIaaSサービスの方だと思われる。

2014年3月に開催されたONS(Open Networking Summit)2014にて発表された内容がYouTubeアップされている。以下に該当部分をピックアップする。

Microsoft Azure - Software Defined Storage : 40GbE RoCE (RDMA)

ONS2014 Keynote (YouTube) - Albert Greenberg, Director of Development, Windows Azure Networking, Microsoft からの引用

f:id:kz_tomo:20140428210451j:plain

  • ストレージコストを抑えるため、ネットワークに投資コモディティーサーバを高速ネットワークで接続した構成。 
  • Erasure Code(消失符号)を活用し、データの冗長性を担保。データライトに対して、3つのコピーライトが実行される。(引用者注:コピーライト完了がクライアントからの応答性能に含まれるため、コピーライトの完了をいかに速くできるかがライト性能のポイントとなり、後述のRDMAが効果を発揮する)

f:id:kz_tomo:20140428211227j:plain

  • 40ギガビットイーサネットRoCE (RDMA over Converged Ethernet)が動作
  • Software Defined Network - 全ての機能はホスト側(RDMA対応NICとドライバソフトウェア)で実現(ネットワーク機器は特別なものではない)
  • オールL3(IPベース)でRDMAが動作(※本稿執筆時点では詳細未公開)
  • 極めて速いレイテンシー:E2Eで2us未満(スライド参照)
  • RDMAにより、ホストCPUの負荷を削減し、圧倒的なコストパフォーマンスを実現

f:id:kz_tomo:20140428211637j:plain

  • 40Gbpsで通信をしている状態でもホストCPU使用率はゼロ(RDMAの特長)
  • 実際にパフォーマンスメーターで0%を確認