qperfを使ってOracle Cloud(OCI)のAD間ネットワークパフォーマンスを測定してみた

*2019/2/14* new
*2019/2/15* 参考に追記, 関連記事のリンク追加
***

# はじめに
Oracle Cloud Infrastructure(OCI)の北米にあるリージョンについて、AD（Availability Domain = データセンター）間のネットワークパフォーマンスを測定してみました。ツールはqperfを使っています。

## やりたいこと
AD間のネットワークパフォーマンス（帯域とレイテンシ）を測定する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109270/71335caa-b451-b99f-347c-7aa6038e6f2e.png)


## 前提
- 北米のPhoenixリージョンとAshburnリージョンのみ確認
- VCNは1つ（3つのADを跨いだネットワーク）
- 以下のcomputeインスタンスを利用
	- Shape : VM.standard2.16(帯域最大16.4 Gbps）
	- OS    : Oracle Linux 7.6( 4.14.35-1844.1.3.el7uek.x86_64 )


# 結果

- 帯域
    - VM.standard2.16の**シェイプの制限値（16Gb/s）まで利用することが出来た。**
- レイテンシ
    - どの組み合わせでも、[公式発表](https://cloud.oracle.com/en_US/iaas/architecture)通り「1ms以下」（片道500μs？）。
        - **片道100μs - 400μs**程度
    - ADの組み合わせによってレイテンシに差があることも分かった（200 - 300μs程度の差）。
        - AshburnではAD1 - AD2間、PhoenixではAD1 - AD3間が最速
- 注意：AD1,2,3が実際にどのデータセンターかはアカウントによって異なります。

|Ashburn     |bandwidth(TCP) | latency(one way) |
|:-----------|:-----------|:-----------|
| AD1 -> AD2 | 16 Gb/s | **111 μs** |
| AD2 -> AD3 | 16 Gb/s | 131 μs |
| AD3 -> AD1 | 16 Gb/s | 291 μs  |
※レイテンシは3回測定した平均値（切り捨て）

|Phoenix     |bandwidth(TCP) | latency(one way) |
|:-----------|:-----------|:-----------|
| AD1 -> AD2 | 16 Gb/s | 402 μs |
| AD2 -> AD3 | 16 Gb/s | 386 μs |
| AD3 -> AD1 | 16 Gb/s | **113 μs**  |
※レイテンシは3回測定した平均値（切り捨て）


### 他のクラウドベンダは？
- AWSのAZ間レイテンシは「通常1ms、最大2ms」とのこと（おそらく往復）
    - 「[AWSを支えるネットワークインフラと要素技術](https://dev.classmethod.jp/cloud/aws/awssummit-2018-day2-h1-2-10-aws-network-infrastructure/)」より
- 測定方法や条件などバラバラなので単純に比較できませんが、いくつか関連記事を見つけました
    - [東京リージョンAZ間のネットワーク性能測定](https://qiita.com/hssh2_bin/items/e7adebb0a7d4924bea51)
    - [AWSアカウント間AZ間レイテンシ](https://qiita.com/sasasin/items/17135d5c5465fc53d385)
    - [AZ間のlatencyについて](AZ間のlatencyについて)
    - [AZ間のレイテンシについて](http://xoxo-infra.hatenablog.com/entry/2013/05/02/032918)
    - [EC2 AZ間のスループット計測 (netperf)](http://xoxo-infra.hatenablog.com/entry/2013/05/20/132453)
    - [AWSでアベイラビリティゾーンをまたいでのアクセスが想像以上に遅かった話](https://qiita.com/rintaro-ishikawa/items/98e26637fbd9ce20a87e)


# 作業

## セットアップ

### セキュリティリスト設定
省略（ingress/egressともに使用するポート/tcpを開ける）

### ファイアーウォール設定

qperfが使う制御用とデータ用のポートをあける
`sudo firewall-cmd --permanent --add-port=19765/tcp --add-port=19766/tcp`
`sudo firewall-cmd --reload`
`sudo firewall-cmd --list-all`
※すべてのインスタンスで実施

### qperfインストール

`$ sudo yum -y install qperf`
※すべてのインスタンスで実施

```shell:インストールされたもの
(1/4): libibverbs-17.2-3.el7.x86_64.rpm                    | 245 kB   00:00
(2/4): librdmacm-17.2-3.el7.x86_64.rpm                     |  61 kB   00:00
(3/4): qperf-0.4.9-3.el7.x86_64.rpm                        |  58 kB   00:00
(4/4): rdma-core-17.2-3.el7.x86_64.rpm                     |  49 kB   00:00
--------------------------------------------------------------------------------
Total                                              3.8 MB/s | 414 kB  00:00
```



## 測定
※Phoenixで実施したもののみ記載

### ①AD1 -> AD2

#### 帯域

- サーバー側(AD2)  
`qperf`

```shell:ad2のcomputeインスタンス
[opc@ad2-instance ~]$ qperf

```

- クライアント側(AD1)  
`qperf -vvs -ip 19766 -t 60 --use_bits_per_sec <IP addr> tcp_bw`  
※オプション等の意味については末尾の「[参考](#参考)」に記載

```shell:ad1のcomputeインスタンス
[opc@ad1-instance ~]$ qperf -vvs -ip 19766 -t 60 --use_bits_per_sec 10.0.101.3 tcp_bw
tcp_bw:
    bw          =    16 Gb/sec	<--★シェイプの制限値
    msg_rate    =  30.4 K/sec
    send_bytes  =   120 GB
    send_msgs   =  1.83 million
    recv_bytes  =   120 GB
    recv_msgs   =  1.83 million
```


#### レイテンシ

- サーバー側(AD2)
`qperf`


- クライアント側(AD1)
`qperf -vvs -ip 19766 -t <IP addr> tcp_lat`


```shell:ad1のcomputeインスタンス
[opc@ad1-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.101.3 tcp_lat
tcp_lat:
    latency         =     402 us	<--★
    msg_rate        =    2.49 K/sec
    loc_send_bytes  =    74.6 KB
    loc_recv_bytes  =    74.6 KB
    loc_send_msgs   =  74,563
    loc_recv_msgs   =  74,562
    rem_send_bytes  =    74.6 KB
    rem_recv_bytes  =    74.6 KB
    rem_send_msgs   =  74,562
    rem_recv_msgs   =  74,562
[opc@ad1-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.101.3 tcp_lat
tcp_lat:
    latency         =     404 us	<--★
    msg_rate        =    2.48 K/sec
    loc_send_bytes  =    74.3 KB
    loc_recv_bytes  =    74.3 KB
    loc_send_msgs   =  74,260
    loc_recv_msgs   =  74,259
    rem_send_bytes  =    74.3 KB
    rem_recv_bytes  =    74.3 KB
    rem_send_msgs   =  74,259
    rem_recv_msgs   =  74,259
[opc@ad1-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.101.3 tcp_lat
tcp_lat:
    latency         =     402 us	<--★
    msg_rate        =    2.49 K/sec
    loc_send_bytes  =    74.6 KB
    loc_recv_bytes  =    74.6 KB
    loc_send_msgs   =  74,584
    loc_recv_msgs   =  74,583
    rem_send_bytes  =    74.6 KB
    rem_recv_bytes  =    74.6 KB
    rem_send_msgs   =  74,584
    rem_recv_msgs   =  74,584
```



### ②AD2 -> AD3

#### 帯域


- サーバー側(AD3)  
`qperf`

```shell:ad3のcomputeインスタンス
[opc@ad3-instance ~]$ qperf

```

- クライアント側(AD2)  
`qperf -vvs -ip 19766 -t 60 --use_bits_per_sec <IP addr> tcp_bw`

```shell:ad2のcomputeインスタンス
[opc@ad2-instance ~]$ qperf -vvs -ip 19766 -t 60 --use_bits_per_sec 10.0.102.3 tcp_bw
tcp_bw:
    bw          =    16 Gb/sec	<--★シェイプの制限値
    msg_rate    =  30.4 K/sec
    send_bytes  =   120 GB
    send_msgs   =  1.83 million
    recv_bytes  =   120 GB
    recv_msgs   =  1.83 million
```

#### レイテンシ

- サーバー側(AD3)
`qperf`


- クライアント側(AD2)
`qperf -vvs -ip 19766 -t <IP addr> tcp_lat`


```shell:ad2のcomputeインスタンス
[opc@ad2-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.102.3 tcp_lat
tcp_lat:
    latency         =     386 us	<--★
    msg_rate        =    2.59 K/sec
    loc_send_bytes  =    77.7 KB
    loc_recv_bytes  =    77.7 KB
    loc_send_msgs   =  77,655
    loc_recv_msgs   =  77,654
    rem_send_bytes  =    77.7 KB
    rem_recv_bytes  =    77.7 KB
    rem_send_msgs   =  77,654
    rem_recv_msgs   =  77,654
[opc@ad2-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.102.3 tcp_lat
tcp_lat:
    latency         =     390 us	<--★
    msg_rate        =    2.57 K/sec
    loc_send_bytes  =      77 KB
    loc_recv_bytes  =      77 KB
    loc_send_msgs   =  77,019
    loc_recv_msgs   =  77,018
    rem_send_bytes  =      77 KB
    rem_recv_bytes  =      77 KB
    rem_send_msgs   =  77,018
    rem_recv_msgs   =  77,018
[opc@ad2-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.102.3 tcp_lat
tcp_lat:
    latency         =     383 us	<--★
    msg_rate        =    2.61 K/sec
    loc_send_bytes  =    78.4 KB
    loc_recv_bytes  =    78.4 KB
    loc_send_msgs   =  78,417
    loc_recv_msgs   =  78,416
    rem_send_bytes  =    78.4 KB
    rem_recv_bytes  =    78.4 KB
    rem_send_msgs   =  78,417
    rem_recv_msgs   =  78,417    
```

### ③AD3 -> AD1

#### 帯域

- サーバー側(AD1)  
`qperf`

```shell:ad1のcomputeインスタンス
[opc@ad1-instance ~]$ qperf

```

- クライアント側(AD3)  
`qperf -vvs -ip 19766 -t 60 --use_bits_per_sec <IP addr> tcp_bw`

```shell:ad3のcomputeインスタンス
[opc@ad3-instance ~]$ qperf -vvs -ip 19766 -t 60 --use_bits_per_sec 10.0.100.4 tcp_bw
tcp_bw:
    bw          =    16 Gb/sec	<--★シェイプの制限値
    msg_rate    =  30.4 K/sec
    send_bytes  =   120 GB
    send_msgs   =  1.83 million
    recv_bytes  =   120 GB
    recv_msgs   =  1.83 million
```

#### レイテンシ

- サーバー側(AD1)
`qperf`

- クライアント側(AD3)
`qperf -vvs -ip 19766 -t 60 --use_bits_per_sec <IP addr> tcp_bw`

```shell:ad3のcomputeインスタンス
[opc@ad3-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.100.4 tcp_lat
tcp_lat:
    latency         =      111 us	<--★
    msg_rate        =     9.04 K/sec
    loc_send_bytes  =      271 KB
    loc_recv_bytes  =      271 KB
    loc_send_msgs   =  271,282
    loc_recv_msgs   =  271,281
    rem_send_bytes  =      271 KB
    rem_recv_bytes  =      271 KB
    rem_send_msgs   =  271,281
    rem_recv_msgs   =  271,281
[opc@ad3-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.100.4 tcp_lat
tcp_lat:
    latency         =      114 us	<--★
    msg_rate        =     8.73 K/sec
    loc_send_bytes  =      262 KB
    loc_recv_bytes  =      262 KB
    loc_send_msgs   =  262,029
    loc_recv_msgs   =  262,028
    rem_send_bytes  =      262 KB
    rem_recv_bytes  =      262 KB
    rem_send_msgs   =  262,028
    rem_recv_msgs   =  262,028
[opc@ad3-instance ~]$ qperf -vvs -ip 19766 -t 60 10.0.100.4 tcp_lat
tcp_lat:
    latency         =      116 us	<--★
    msg_rate        =     8.65 K/sec
    loc_send_bytes  =      259 KB
    loc_recv_bytes  =      259 KB
    loc_send_msgs   =  259,450
    loc_recv_msgs   =  259,449
    rem_send_bytes  =      259 KB
    rem_recv_bytes  =      259 KB
    rem_send_msgs   =  259,449
    rem_recv_msgs   =  259,449    
```

# 参考・補足情報

## マニュアル他
- OCIマニュアルでは[iperf3](https://iperf.fr/)というツールを使っていました（「[Network Performance](https://docs.cloud.oracle.com/iaas/Content/Network/Concepts/networkperformance.htm)」）
- OCi Computeインスタンスのシェイプ毎のNW帯域は「[Compute Shapes](https://docs.cloud.oracle.com/iaas/Content/Compute/References/computeshapes.htm)」を参照
- [FAQ](https://cloud.oracle.com/en_US/networking/vcn/faq#peering)には、VCNを分けてLPGで接続しても変わらないと書いてある。いつか検証してみたい。

```text:FAQサイトより引用
Is there a performance impact based on throughput and latency 
over the established local peering between two VCNs?

No. Throughput and latency should be close to intra-VCN connections. 
Traffic over the local peering has similar availability and 
bandwidth constraints as the traffic between instances in a VCN.
```

## qperfについて
- qperfの使い方については以下を参照
    - 「[How to use qperf to measure network bandwidth and latency performance? ](https://access.redhat.com/solutions/2122681)」
- qperfについて、以下manより抜粋

```shell:qperf
NAME
       qperf - Measure RDMA and IP performance

SYNOPSIS
       qperf
       qperf SERVERNODE [OPTIONS] TESTS
       
DESCRIPTION
       qperf  measures  bandwidth  and latency between two nodes.  It can work
       over TCP/IP as well as the RDMA transports.  On one of the nodes, qperf
       is typically run with no arguments designating it the server node.  One
       may then run qperf on a client node  to  obtain  measurements  such  as
       bandwidth, latency and cpu utilization.

       In  its  most  basic  form,  qperf is run on one node in server mode by
       invoking it with no arguments.  On the other node, it is run  with  two
       arguments:  the  name  of  the  server node followed by the name of the
       test.  A list of tests can be found in the section, TESTS.   A  variety
       of options may also be specified.
```

```shell
       -ip, --ip_port Port
              Use Port to run the socket tests.  This is different from --lis‐
              ten_port  which is used for synchronization.  This is only rele‐
              vant for the socket tests and  refers  to  the  TCP/UDP/RDS/SCTP
              port that the test is run on.
              

       -t, --time Time
              Set test duration to  Time.   Specified  in  seconds  however  a
              trailing  m, h or d indicates that the time is specified in min‐
              utes, hours or days respectively.

       -v, --verbose
              Provide more detailed output.  Turns on -vc, -vs, -vt and -vu.

       -vs, --verbose_stat
              Provide information on statistics.

       -vv, --verbose_more
              Provide even more detailed output.  Turns on  -vvc,  -vvs,  -vvt
              and -vvu.
```

```shell
       tcp_bw TCP streaming one way bandwidth

       tcp_lat
              TCP one way latency
```

以上