Blog

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

L2/L3冗長化:MLAG+VRRP/MAGP

Mellanoxスイッチを用いた冗長ネットワークの構成例(L2/L3)

構成例:

Mellanox Ethernet Switch : SX1036等(モデル問わず)

Switch Software : MLNX OS 3.3.5006以降

 f:id:kz_tomo:20140811171149j:plain

構成例についての説明:

  • MLAG (Multi-chassis LAG):2つのスイッチを1つのL2スイッチとして動作させ、スイッチをまたがってLAGを構成する機能です。いわゆる普通のMLAGです。冗長化されたペアのポートは、1つの物理ポートとして外からは見え、対向のホストや別スイッチも同様の(1つの物理ポートとして見える)冗長ポート(bondingやLAG)と接続することができます。1つのパスを複数パスLAG構成ともできます。1つのLAGに所属するリンク上限は16本。スイッチ間接続も最大16本のLAG構成も可能です。スイッチをまたがって冗長パスを構成しているため、パス障害、スイッチ障害、スイッチ間接続障害の想定される全ての箇所で障害が発生した場合にも通信を継続することが可能です。
  • VRRP(Virtual Router Redundancy Protocol):2つのスイッチでL3 IPアドレス冗長化する機能です。優先度設定により、優先度が高いスイッチがMaster、優先度が低いスイッチがBackupとなります。VRRPは標準化された規格なので、標準的なVRRPです。一方のスイッチがダウンした場合には、他方のスイッチがIPアドレスを引き継ぎます。
  • MAGP (Multi-active Gateway Protocol):機能としてはVRRPと同様ですが、VRRPがActive/Standby型の動作に対し、MAGPはActive/Activeの動作をサポートします。ベンダユニークの機能です(他のスイッチでも同様のベンダユニーク機能あり)。MAGPは、MLAG構成で設定可能です。

複数サブネットのデフォルトゲートウェイ

2つのスイッチで冗長化するL3 IPアドレスとして、複数IPアドレス(同一サブネット及び異なるサブネットのどちらでも可能)を設定することができます。

上記構成例では、VLANなし、VLAN=10、VLAN=20、VLAN=30の4つのサブネットがホスト側に設定されていますが、例えば、4つのサブネットそれぞれに対するデフォルトゲートウェイを2台のスイッチに仮想IPアドレス(VIP:Virtual IP address)として設定することができます。MAGP(Active/Active)、VRRP(Active/Standby)共に可能です。VRRPを使用する場合、スイッチ負荷を分散するため、MasterとBackupを均等に割り当てるのが推奨です。

※特別な理由がなければ、可用性、負荷分散の観点から、Active/Activeの構成であるMLAG+MAGPでの運用が推奨です。

 

おまけ(Open MLAG)

最近、Mellanoxはスイッチのソフトウェア部分をオープンにする取り組みを進めていますが、世界で初めてMLAGの実装をオープンソースとして公開した、とプレスリリースをしています。なぜMLAGだけ公開しているのかは謎ですが。。。

Mellanox Contributes the World's First Open Source Ethernet Switch MLAG Implementation (NASDAQ:MLNX)

スイッチのソフトウェアとか、Mellanoxの動向に興味があれば、下記のGitHubにMLAGソースコードがあるのでチェックしてみてください。

open-ethernet/MLAG · GitHub

 

 

 

NICでVLAN毎にQoS(帯域上限)を設定する方法(Linux)

VLAN毎にQoS(帯域上限)をNICで設定する例を説明します。

例えば40GbEネットワークを検討する場合、ある特定のトラフィックが帯域を使い切ってしまうことが懸念され、10GbE複数本を統合するのに躊躇してしまう、というような場合、QoS設定をしておくことで帯域をトラフィック毎に使い分けることができます。(実際には非常に速いオールフラッシュストレージ等を接続しない限り、40Gbpsを使い切ることはめったにないと思いますが、運用上安心できると思います)

※Mellanox NICの場合の例

構成例:

  • OS : Ubuntu14.04LTS
  • NIC : Mellanox ConnectX-3Pro (40GbE) Dual Port
  • Driver : MLNX OFED 2.2-1.0.1
  • MTU=1500 byte (デフォルト)

 QoS設定例:

f:id:kz_tomo:20140811165926j:plain

VLAN=10 (IP address=12.0.10.2): 1Gbps

VLAN=20 (IP address=12.0.20.2): 5Gbps

VLAN=30 (IP address=12.0.30.2): 帯域制限なし

 ※下記では一方のNICのみの設定ですが、通信ペア共に設定します(NICからの送信帯域を制限する設定)。

1.VLANインタフェース作成

# vconfig add eth1 10
# vconfig add eth1 20
# vconfig add eth1 30

2.IPアドレス割り当て(ここまではQoSとは直接関係ない設定)

# ifconfig eth1.10 12.0.10.2 netmask 255.255.255.0
# ifconfig eth1.20 12.0.20.2 netmask 255.255.255.0
# ifconfig eth1.30 12.0.30.2 netmask 255.255.255.0

3.送信Socket priorityをUser priority(UP)に割り当て

//VLAN 10 : socket priority 0-7(all) => user priority 1
//VLAN 20 : socket priority 0-7(all) => user priority 3
//VLAN 30 : socket priority 0-7(all) => user priority 5

# for i in {0..7}; do vconfig set_egress_map eth1.10 $i 1 ; done
# for i in {0..7}; do vconfig set_egress_map eth1.20 $i 3 ; done
# for i in {0..7}; do vconfig set_egress_map eth1.30 $i 5 ; done

<設定確認>

送信priority 0~7とuser priorityとのマッピングが下記で確認できます。

# cat /proc/net/vlan/eth1.10
eth1.10 VID: 10 REORDER_HDR: 1 dev->priv_flags: 1
total frames received 0
total bytes received 0
Broadcast/Multicast Rcvd 0

total frames transmitted 8
total bytes transmitted 648
Device: bond0
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
EGRESS priority mappings: 0:1 1:1 2:1 3:1 4:1 5:1 6:1 7:1

# cat /proc/net/vlan/eth1.20
eth1.20 VID: 20 REORDER_HDR: 1 dev->priv_flags: 1
total frames received 0
total bytes received 0
Broadcast/Multicast Rcvd 0

total frames transmitted 8
total bytes transmitted 648
Device: bond0
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
EGRESS priority mappings: 0:3 1:3 2:3 3:3 4:3 5:3 6:3 7:3

# cat /proc/net/vlan/eth1.30
eth1.30 VID: 30 REORDER_HDR: 1 dev->priv_flags: 1
total frames received 0
total bytes received 0
Broadcast/Multicast Rcvd 0

total frames transmitted 8
total bytes transmitted 648
Device: bond0
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
EGRESS priority mappings: 0:5 1:5 2:5 3:5 4:5 5:5 6:5 7:5

4.NICQoS設定(Mellanox NICの場合の例)

// user priority 0 => TC(Traffic Class) 0
// user priority 1 => TC(Traffic Class) 0
// user priority 2 => TC(Traffic Class) 1
// user priority 3 => TC(Traffic Class) 1
// user priority 4 => TC(Traffic Class) 2
// user priority 5 => TC(Traffic Class) 2
// user priority 6 => TC(Traffic Class) 3
// user priority 7 => TC(Traffic Class) 3
// Transmission algorithm = strict for TC0-3
// TC minimum bandwidth = 0% for TC0-3 (strict)
// Rate limit : 1Gbps:TC0, 5Gbps:TC1

というように設定するコマンドが下記です。
# mlnx_qos -i eth1 --prio_tc=0,0,1,1,2,2,3,3 --tsa=strict,strict,strict,strict --tcbw=0,0,0,0 --ratelimit=1,5

 

5.性能検証

実際にQoSが効いていることを確認します(本例ではiperfで測定を実施)。

VLAN=10(帯域制限=1Gbps)

# iperf -c 12.0.10.1 -P 16
------------------------------------------------------------
Client connecting to 12.0.10.1, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 18] local 12.0.10.2 port 51263 connected with 12.0.10.1 port 5001
[ 5] local 12.0.10.2 port 51250 connected with 12.0.10.1 port 5001
[ 4] local 12.0.10.2 port 51249 connected with 12.0.10.1 port 5001
[ 3] local 12.0.10.2 port 51248 connected with 12.0.10.1 port 5001
[ 6] local 12.0.10.2 port 51251 connected with 12.0.10.1 port 5001
[ 7] local 12.0.10.2 port 51252 connected with 12.0.10.1 port 5001
[ 8] local 12.0.10.2 port 51253 connected with 12.0.10.1 port 5001
[ 9] local 12.0.10.2 port 51254 connected with 12.0.10.1 port 5001
[ 10] local 12.0.10.2 port 51255 connected with 12.0.10.1 port 5001
[ 11] local 12.0.10.2 port 51256 connected with 12.0.10.1 port 5001
[ 13] local 12.0.10.2 port 51257 connected with 12.0.10.1 port 5001
[ 12] local 12.0.10.2 port 51258 connected with 12.0.10.1 port 5001
[ 14] local 12.0.10.2 port 51259 connected with 12.0.10.1 port 5001
[ 15] local 12.0.10.2 port 51260 connected with 12.0.10.1 port 5001
[ 16] local 12.0.10.2 port 51261 connected with 12.0.10.1 port 5001
[ 17] local 12.0.10.2 port 51262 connected with 12.0.10.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 153 MBytes 128 Mbits/sec
[ 5] 0.0-10.0 sec 146 MBytes 123 Mbits/sec
[ 7] 0.0-10.0 sec 10.6 MBytes 8.90 Mbits/sec
[ 17] 0.0-10.0 sec 139 MBytes 117 Mbits/sec
[ 8] 0.0-10.0 sec 154 MBytes 128 Mbits/sec
[ 14] 0.0-10.0 sec 146 MBytes 123 Mbits/sec
[ 13] 0.0-10.0 sec 139 MBytes 116 Mbits/sec
[ 15] 0.0-10.0 sec 150 MBytes 126 Mbits/sec
[ 10] 0.0-10.0 sec 144 MBytes 121 Mbits/sec
[ 9] 0.0-10.1 sec 11.2 MBytes 9.37 Mbits/sec
[ 6] 0.0-10.1 sec 10.4 MBytes 8.62 Mbits/sec
[ 18] 0.0-10.1 sec 10.5 MBytes 8.71 Mbits/sec
[ 11] 0.0-10.1 sec 11.0 MBytes 9.12 Mbits/sec
[ 12] 0.0-10.1 sec 10.4 MBytes 8.61 Mbits/sec
[ 4] 0.0-10.1 sec 10.5 MBytes 8.70 Mbits/sec
[ 16] 0.0-10.1 sec 11.2 MBytes 9.32 Mbits/sec
[SUM] 0.0-10.1 sec 1.23 GBytes 1.04 Gbits/sec

VLAN=20 (帯域制限=5Gbps)

# iperf -c 12.0.20.1 -P 16
------------------------------------------------------------
Client connecting to 12.0.20.1, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 18] local 12.0.20.2 port 36567 connected with 12.0.20.1 port 5001
[ 4] local 12.0.20.2 port 36553 connected with 12.0.20.1 port 5001
[ 5] local 12.0.20.2 port 36554 connected with 12.0.20.1 port 5001
[ 6] local 12.0.20.2 port 36555 connected with 12.0.20.1 port 5001
[ 3] local 12.0.20.2 port 36552 connected with 12.0.20.1 port 5001
[ 7] local 12.0.20.2 port 36556 connected with 12.0.20.1 port 5001
[ 8] local 12.0.20.2 port 36557 connected with 12.0.20.1 port 5001
[ 10] local 12.0.20.2 port 36559 connected with 12.0.20.1 port 5001
[ 9] local 12.0.20.2 port 36558 connected with 12.0.20.1 port 5001
[ 11] local 12.0.20.2 port 36560 connected with 12.0.20.1 port 5001
[ 12] local 12.0.20.2 port 36561 connected with 12.0.20.1 port 5001
[ 14] local 12.0.20.2 port 36562 connected with 12.0.20.1 port 5001
[ 13] local 12.0.20.2 port 36563 connected with 12.0.20.1 port 5001
[ 16] local 12.0.20.2 port 36564 connected with 12.0.20.1 port 5001
[ 15] local 12.0.20.2 port 36565 connected with 12.0.20.1 port 5001
[ 17] local 12.0.20.2 port 36566 connected with 12.0.20.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 7] 0.0-10.0 sec 735 MBytes 617 Mbits/sec
[ 11] 0.0-10.0 sec 694 MBytes 583 Mbits/sec
[ 14] 0.0-10.0 sec 627 MBytes 526 Mbits/sec
[ 18] 0.0-10.0 sec 697 MBytes 584 Mbits/sec
[ 4] 0.0-10.0 sec 572 MBytes 479 Mbits/sec
[ 6] 0.0-10.0 sec 735 MBytes 616 Mbits/sec
[ 3] 0.0-10.0 sec 78.0 MBytes 65.4 Mbits/sec
[ 9] 0.0-10.0 sec 572 MBytes 479 Mbits/sec
[ 12] 0.0-10.0 sec 77.8 MBytes 65.2 Mbits/sec
[ 16] 0.0-10.0 sec 78.1 MBytes 65.5 Mbits/sec
[ 15] 0.0-10.0 sec 749 MBytes 627 Mbits/sec
[ 5] 0.0-10.0 sec 80.1 MBytes 67.1 Mbits/sec
[ 8] 0.0-10.0 sec 78.4 MBytes 65.6 Mbits/sec
[ 10] 0.0-10.0 sec 78.1 MBytes 65.3 Mbits/sec
[ 13] 0.0-10.0 sec 78.4 MBytes 65.5 Mbits/sec
[ 17] 0.0-10.0 sec 78.5 MBytes 65.6 Mbits/sec
[SUM] 0.0-10.0 sec 5.87 GBytes 5.02 Gbits/sec

VLAN=30(帯域制限なし)

# iperf -c 12.0.30.1 -P 16
------------------------------------------------------------
Client connecting to 12.0.30.1, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 12.0.30.2 port 41096 connected with 12.0.30.1 port 5001
[ 4] local 12.0.30.2 port 41097 connected with 12.0.30.1 port 5001
[ 5] local 12.0.30.2 port 41098 connected with 12.0.30.1 port 5001
[ 18] local 12.0.30.2 port 41110 connected with 12.0.30.1 port 5001
[ 6] local 12.0.30.2 port 41099 connected with 12.0.30.1 port 5001
[ 7] local 12.0.30.2 port 41100 connected with 12.0.30.1 port 5001
[ 9] local 12.0.30.2 port 41102 connected with 12.0.30.1 port 5001
[ 8] local 12.0.30.2 port 41101 connected with 12.0.30.1 port 5001
[ 10] local 12.0.30.2 port 41103 connected with 12.0.30.1 port 5001
[ 11] local 12.0.30.2 port 41104 connected with 12.0.30.1 port 5001
[ 12] local 12.0.30.2 port 41105 connected with 12.0.30.1 port 5001
[ 13] local 12.0.30.2 port 41106 connected with 12.0.30.1 port 5001
[ 14] local 12.0.30.2 port 41107 connected with 12.0.30.1 port 5001
[ 15] local 12.0.30.2 port 41108 connected with 12.0.30.1 port 5001
[ 16] local 12.0.30.2 port 41109 connected with 12.0.30.1 port 5001
[ 17] local 12.0.30.2 port 41111 connected with 12.0.30.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 3.80 GBytes 3.26 Gbits/sec
[ 4] 0.0-10.0 sec 1.97 GBytes 1.69 Gbits/sec
[ 5] 0.0-10.0 sec 3.08 GBytes 2.65 Gbits/sec
[ 6] 0.0-10.0 sec 1.95 GBytes 1.68 Gbits/sec
[ 7] 0.0-10.0 sec 1.72 GBytes 1.48 Gbits/sec
[ 12] 0.0-10.0 sec 3.54 GBytes 3.04 Gbits/sec
[ 13] 0.0-10.0 sec 2.09 GBytes 1.80 Gbits/sec
[ 14] 0.0-10.0 sec 3.70 GBytes 3.18 Gbits/sec
[ 18] 0.0-10.0 sec 3.57 GBytes 3.07 Gbits/sec
[ 9] 0.0-10.0 sec 1.86 GBytes 1.59 Gbits/sec
[ 8] 0.0-10.0 sec 4.06 GBytes 3.49 Gbits/sec
[ 10] 0.0-10.0 sec 3.58 GBytes 3.07 Gbits/sec
[ 11] 0.0-10.0 sec 1.75 GBytes 1.51 Gbits/sec
[ 15] 0.0-10.0 sec 3.42 GBytes 2.94 Gbits/sec
[ 16] 0.0-10.0 sec 2.05 GBytes 1.76 Gbits/sec
[ 17] 0.0-10.0 sec 1.87 GBytes 1.60 Gbits/sec
[SUM] 0.0-10.0 sec 44.0 GBytes 37.8 Gbits/sec

 6. 考察

性能測定の結果、各VLANトラフィックが設定通りの帯域制限で動作していることが確認できました。

各VLANにて同時にトラフィックを流した場合は、単独で流した場合よりは変動幅はあるものの、運用上問題ないレベルで性能確認ができています。

本設定はサーバ再起動すると残らないので、起動時に実行されるスクリプトで実行するよう設定することで運用することができます。

7.補足 (bonding構成の場合)

補足として、bonding構成の場合についてです。

例として、eth1とeth2をbondingし、bond0とした場合ですが、

  • 「3.送信Socket priorityをUser priority(UP)に割り当て」まではeth1の代わりにbond0を指定
  • 「4.NICQoS設定(Mellanox NICの場合の例)」では、eth1とeth2の両方でコマンドを実行(下記)

# mlnx_qos -i eth1 --prio_tc=0,0,1,1,2,2,3,3 --tsa=strict,strict,strict,strict --tcbw=0,0,0,0 --ratelimit=1,5

# mlnx_qos -i eth2 --prio_tc=0,0,1,1,2,2,3,3 --tsa=strict,strict,strict,strict --tcbw=0,0,0,0 --ratelimit=1,5

でOKです。

 

10GbE2本、冗長含めて計4本を1つのサーバに接続して運用されている仮想化環境やクラウド環境は多いと思いますが、今回紹介した方法を用いれば、Dual portの40GbEカード1枚に統合し、しかも帯域制限でVLANトラフィック毎に帯域を分けることができます。(NIC送信帯域を制限する方法なので、スイッチの設定は必要ありません)

 

 

 

 

ストレージ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