Azure Storage:Premium SSD はシングルスレッド書き込みが苦手？

# 概要

- AzureとvSphereでIOベンチマークを比較
- AzureとvSphereでデータベース処理を比較
- データベースの工夫 on Azure Storage
 
# はじめに
前回はAzure Premium SSDのキャッシュなしと読み取りキャッシュの違いをデータベースの観点から調査しました。今回はAzureとVMware vSphereでIOの違いを調査したいと思います。

[Azure Premium SSDとデータベースとキャッシュ](https://qiita.com/tsunenorikan/items/9e666a11426dc72fc001 "Qiita")

# 比較する環境
Azureを2環境、vSphereを1環境の合計3環境で比較しました。Azureの違いはデータディスクが**単一ディスク**か **複数ディスクでストライピング(RAID0)** かだけで他は同じです。vSphereはオンプレミスで一般的な仮想環境になります。

<dl>
  <dt>Azure-1</dt>
  <dd>Instance DS4v2 (CPU:8 Memory:28GB)</dd>
  <dd>S10 (Standard SSD 128GB     500IOPS)     Cache:ReadWrite OS Disk   </dd>
  <dd><strong>P40 (Premium SSD 2TB      7,500IOPS)</strong>     Cache:ReadOnly Data Disk</dd>
  <dd>Windows Server 2016</dd>
  <dd>IBM Db2 V11.1</dd>
  <dt>Azure-2</dt>
  <dd>Instance DS4v2 (CPU:8 Memory:28GB)</dd>
  <dd>S10 (Standard SSD 128GB     500IOPS)     Cache:ReadWrite OS Disk   </dd>
  <dd><strong>P30 (Premium SSD 1TB  5,000IOPS)×4</strong>   Cache:ReadOnly Data Disk </dd>
  <dd>Windows Server 2016</dd>
  <dd>IBM Db2 V11.1</dd>
  <dt>vSphere</dt>
  <dd>VMware vSphere 6 (Xeon E5-2620 Hyper-Threading:on)</dd>
  <dd>SAS共有ストレージ 600GB(15K)×8    RAID6</dd>
  <dd>GuestVM CPU:8vCPU Memory:8GB Disk:1,300GB
  <dd>Windows Server 2012</dd>
  <dd>IBM Db2 V10.5</dd>
</dl>

[SAS:Serial Attached SCSI](https://ja.wikipedia.org/wiki/Serial_Attached_SCSI "ウィキペディアへ")

# IOベンチマーク
[CrystalDiskMark 7](https://crystalmark.info/ "ダウンロードサイトへ")でIOPSを測定しました。Azure-1がデータディスクが **単体ディスク** 、Azure-2が **ストライピング(RAID0)** です。Qは待ち行列数、Tはスレッド数になり、Q8T1ですと待ち行列数が8、スレッド数が1になります。

| IOPS     | Azure-1  | Azure-2  | vSphere  | 評価 |
|:--|--:|--:|--:|:-:|                         
| SEQ1M Q8T1 Read   | 128.79   | 257.40   | 656.22   | **Azure-2 << vSphere**| 
| SEQ1M Q8T1 Write  | 127.60   | 256.38   | 481.45   | Azure-2 < vSphere|
| SEQ1M Q1T1 Read   | 128.81   | 257.39   | 324.54   | Azure-2 < vSphere|
| SEQ1M Q1T1 Write  | 42.60    | 74.40    | 257.02   | **Azure-2 <<< vSphere** |
| RND4K Q32T16 Read | 16484.62 | 32970.70 | 39069.82 | Azure-2 < vSphere |
| RND4K Q32T16 Write| 8087.40  | 22403.81 | 20116.46 | Azure-2 > vSphere |
| RND4K Q1T1 Read   | 11048.83 | 11454.35 | 4499.27  | **Azure-2 >> vSphere** |
| RND4K Q1T1 Write  | 385.74   | 415.04   | 2324.71  | **Azure-2 <<<<< vSphere** |

**Azure-2**と**vSphere**を比較し、2倍以上の差がついたものは太字にしています。SEQ1M Q8T1 Readは**2倍の差、** SEQ1M Q1T1 Writeは**3倍の差**、RND4K Q1T1 Writeは**5倍の差**で**vSphereが勝っています**。逆にRND4K Q1T1 Readは**2倍の差**で**Azureが勝っています。** また、スループットもIOPSと変わらない結果になりました。

<details><summary>スループットの詳細</summary><div>

| MB/s              | Azure-1 | Azure-2  | vSphere  | 評価 |
|:--|--:|--:|--:|:-:|                         
| SEQ1M Q8T1 Read   | 135.04  | 269.91 | 688.096 | **Azure-2 << vSphere**| 
| SEQ1M Q8T1 Write  | 133.79  | 268.83 | 504.839 | Azure-2 < vSphere|
| SEQ1M Q1T1 Read   | 135.07  | 269.89 | 340.300 | Azure-2 < vSphere|
| SEQ1M Q1T1 Write  | 44.67   | 78.01  | 269.500 | **Azure-2 <<< vSphere** |
| RND4K Q32T16 Read | 67.52   | 135.05 | 160.030 | Azure-2 < vSphere |
| RND4K Q32T16 Write| 33.13   | 91.77  | 82.397  | Azure-2 > vSphere |
| RND4K Q1T1 Read   | 45.26   | 46.92  | 18.429  | **Azure-2 >> vSphere** |
| RND4K Q1T1 Write  | 1.58    | 1.70   | 9.522   | **Azure-2 <<<<< vSphere** |

</div></details>

また、**Azure-1(単体ディスク)**と**Azure-2(ストライピング)**を比較すると、RND4K Q32T16 Writeが**Azure公式に近いIOPS**の結果になりました。

|ケース|ベンチマーク|Azure公式|ディスクサイズ|
|:--:|--:|--:|:--:|    
| Azure-1 | 8087.40  | 7500  | P40(7500)×1 |
| Azure-2 | 22403.81 | 20000 | P30(5000)×4 |

[Azureで利用できるディスクの種類](https://docs.microsoft.com/ja-jp/azure/virtual-machines/disks-types "Azure公式サイトへ")


先ほどのベンチマークで**Azureはシングルスレッド書き込みのパフォーマンスが低い**という結果になりました。 ただ、Azureのケースが両方とも読み取り専用キャッシュでした。**書き込みはキャッシュなしの方がパフォーマンスが高い**とAzure公式にあるのでキャッシュなしも比較してみます。
Azure-2Nがキャッシュなし、Azure-2Rが読み取り専用キャッシュです。どちらもAzure-2をベースとして他のリソースは同じです。

| IOPS     | Azure-2N  | Azure-2R  | vSphere  | 評価 |
|:--|--:|--:|--:|:-:|                         
| SEQ1M Q8T1 Read   | 372.39   | 257.40   | 656.22   | None < vSphere  | 
| SEQ1M Q8T1 Write  | 374.34   | 256.38   | 481.45   | None < vSphere  |
| SEQ1M Q1T1 Read   | 29.40    | 257.39   | 324.54   | **None <^10< vSphere**|
| SEQ1M Q1T1 Write  | 84.01    | 74.40    | 257.02   | **None <<< vSphere**  |
| RND4K Q32T16 Read | 21091.06 | 32970.70 | 39069.82 | None < vSphere  |
| RND4K Q32T16 Write| 20510.50 | 22403.81 | 20116.46 | None > vSphere  |
| RND4K Q1T1 Read   | 100.59   | 11454.35 | 4499.27  | **None <^43< vSphere** |
| RND4K Q1T1 Write  | 440.43   | 415.04   | 2324.71  | **None <<<<< vSphere**  |

**キャッシュなし(Azure-2N(None))**と**vSphere**を比較し、2倍以上の差がついたものは太字にしています。書き込み速度は若干向上した程度で **大勢は変わらず、** 読み取り速度でvSphereに大差をつけられる結果になりました。やはり、**Azure Premium SSD はシングルスレッド書き込みが苦手**のようです。

# データベースでのパフォーマンスの違い
データベースはDb2を使用しています。OLTPアプリは対話型で照会の割合が多いものを人間が操作して評価しています。数値による評価ではなく申し訳ないです。インポートは274個のテーブルをファイルから取り込む時間を計測しています。DBバックアップはバックアップファイルの大きさが35GBです。
[OLTP:Online Transaction Processing](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%87%A6%E7%90%86 "ウィキペディアへ")

|   | Azure-2 | vSphere | 評価 |
|:--|:--:|:--:|:--:|                         
| OLTPアプリ |vSphereと同じ | 普通 | Azure-2 = vSphere | 
| インポート | 10分         | 6分  | Azure-2 < vSphere |
| DBバックアップ | 1時間54分 | 34分 | **Azure-2 <<< vSphere** | 

OLTPアプリの応答速度には大きな違いはありませんでした。インポートはvSphereが優れます。DBバックアップは**3倍の差**で**vSphereが勝っています。** SEQ1M Q8T1 ReadとSEQ1M Q1T1 Writeの結果がそのままDBバックアップの時間の差になっています。

# データベースの工夫 on Azure Storage
vSphereで稼働していたデータベースをそのままAzureに移行するとインポート、DBバックアップ等、シーケンシャルな処理が遅いということがわかりました。特にDBバックアップは時間が3倍以上かかります。34分が1時間54分かかるとさすがに文句が出そうですので工夫してみます。ここではバックアップ処理を並列化できないかを検討します。Db2ですとテーブルを配置するテーブルスペース(TS)を分散させるとバックアップの並列度が上がります。

|   | Azure-2(TS分散前) | Azure-2(TS分散後) | vSphere(TS分散前) |
|:--|:--:|:--:|:--:|
| DBバックアップ | 1時間54分 | 16分 | 34分 |

TSを適切に分散させると並列度が上がり速度が劇的に向上しました。当然、並列度はvCPUの数に影響を受けます。

# まとめ
#### 評価
Azure Premium SSD はシングルスレッド処理、特に書き込みが苦手のようです。Db2の場合、それがインポート、DBバックアップに影響します。OLTPアプリがvSphereと変わらない応答速度なのは小さなデータ(主に4KB)の読み取り処理が大半ですので、RND4K Q1T1 ReadのIOPSに依存するからだと考えます。[前回](https://qiita.com/tsunenorikan/items/9e666a11426dc72fc001 "Qiita")の記事でキャッシュなしのRND4K Q1T1 ReadがIOPSが低く、それがOLTPアプリの応答速度が低下につながることからもわかります。
#### Azure Storage公式
公式には「Azure では、**超並列のプラットフォームとして Premium Storage が設計されました。** そのため、マルチスレッド アプリケーションは、シングルスレッド アプリケーションよりもはるかに高いパフォーマンスを実現します。 マルチスレッド アプリケーションでは、タスクを複数のスレッドに分割し、VM とディスクのリソースを最大限に活用することで実行効率を高めます。」とあります。

[Azure Premium Storage: 高パフォーマンス用に設計する](https://docs.microsoft.com/ja-jp/azure/virtual-machines/premium-storage-performance "Azure公式サイトへ")

#### 考察
DBバックアップは並列度を上げることで処理時間を短縮することができました。大量のデータをインポート、バックアップする場合は処理の並列化を検討する必要があります。