結局Volumeは何個作成するのが良いの？【仕様を加味したVolume設計】

## はじめに
ONTAPおける**Volumeはデータを保存し、管理するための単位であり、容量やパフォーマンスの要件に応じて作成する必要があります。**

例えば、ファイルサーバ用途の場合、部署毎にVolumeを作成する事でデータの整理やアクセス制御の管理が容易になります。
また、**セキュリティ要件(UNIX, NTFS)によって分けて作成**するような場合もありますし、**パフォーマンス要件が異なる場合には、SSDベースのVolumeや容量重視のHDDベースのVolumeを作成することが有効**な場合もあります。

但し、同一のDisk構成で特にセキュリティ的にも分ける必要が無い場合には、1つの大きなVolumeを作成して提供するのは仕様上最適であると言えるのでしょうか？
本記事では、**ONTAP仕様に基づくVolume作成の最適個数について記載致します。**

<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/e25a81fc-9740-e7d1-9aea-1754ac1c64c2.png>



## とりあえず結論

- **Volumeは複数作成が推奨で、Aggregateあたり4 Volume**
- **Aggregateも複数作成が推奨**
- **1 Volume環境の推奨は相当昔のONTAPの話(15年位前？)**


:::note info
Aggregateの複数作成については、障害時の影響をどうするかでも変わってきます。
障害時にコントローラへI/O集約してLatency上昇するのを抑えたいという点においては、通常時にはAggregateはコントローラあたり1つとする事で、影響度を下げる事はできます。
:::
<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/ee8f4126-e244-568d-76a6-6ddf7072ef52.png>

## データ並列処理ついて

ONTAPは、最初はシングルCPU環境を想定して設計されていましたが、ハードウェアのクロック数競争が終わり、マルチコア化が進むにつれて、ONTAPもCSMP（Coarse Symmetric Multi Processing）モデルに移行しました。これにより、搭載されたCPUで負荷を分散するように設計されています。

また、CPUリソースは処理ごとに「ドメイン」という単位で管理されており、各ドメインは、シングルスレッドで動作するものとマルチスレッドで動作するものがあります。

ONTAPのファイルシステムであるWAFLのデータ処理(ユーザアクセス処理)については、**過去のONTAPではシングルスレッドで動くKahunaドメインで処理されていましたが、WAFL Exemptドメインに下請けすることで分散処理が行われるように変わっています。**


<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/0d081269-9cc2-5785-8aa7-43a299a242be.png>


ドメインの処理については、CLIですとNode shellからDiag　モードでsysstat -Mで確認するか、HarvestのNodeに関する項目からCPU Busy Domainグラフで利用状況を確認できます。

```bash:
> node run -node コントローラ名 -command "priv set diag;sysstat -M 1"
Warning: These diagnostic commands are for use by NetApp
         personnel only.
ANY1+ ANY2+ ANY3+ ANY4+ ANY5+ ANY6+ ANY7+ ANY8+ ANY9+ ANY10+ ANY11+ ANY12+ ANY13+ ANY14+ ANY15+ ANY16+ ANY17+ ANY18+ ANY19+ ANY20+  AVG CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11 CPU12 CPU13 CPU14 CPU15 CPU16 CPU17 CPU18 CPU19 Nwk_Lg Nwk_Exmpt Protocol Storage Raid Raid_Ex Xor_Ex Target Kahuna WAFL_Ex(Kahu) WAFL_MPClean SM_Exempt Exempt SSAN_Ex Intr Host  Ops/s   CP
  32%   15%   10%    7%    4%    3%    2%    1%    1%     1%     0%     0%     0%     0%     0%     0%     0%     0%     0%     0%   4%   3%   3%   2%   2%   3%   3%   4%   2%   3%   3%    2%    1%    2%    1%    1%   10%    8%   18%    8%   10%     0%       10%       0%      1%   0%      0%     0%    0%     0%     13%(  0%)          0%        0%  19%      0%  12%  28%   1049   0%
  50%   26%   15%    9%    5%    3%    2%    1%    1%     1%     0%     0%     0%     0%     0%     0%     0%     0%     0%     0%   6%   3%   3%   2%   2%   3%   3%   3%   2%   4%   4%    2%    0%    2%    1%    1%   24%   14%   19%   14%   19%     0%       18%       0%      1%   0%      0%     0%    0%     0%     22%(  1%)          0%        0%  29%      0%  13%  38%   2144   0%
  31%   16%   10%    7%    5%    3%    2%    1%    1%     1%     0%     0%     0%     0%     0%     0%     0%     0%     0%     0%   4%   3%   3%   2%   2%   3%   3%   3%   2%   3%   3%    3%    1%    2%    1%    1%   13%    9%   12%    9%   12%     0%       13%       0%      1%   0%      1%     0%    0%     0%     18%(  0%)          0%        0%  19%      0%  13%  20%   1606   0%
  45%   27%   17%   10%    6%    4%    3%    2%    1%     1%     0%     0%     0%     0%     0%     0%     0%     0%     0%     0%   6%   3%   3%   3%   3%   3%   3%   3%   3%   6%   3%    3%    1%    2%    1%    1%   20%   14%   19%   16%   20%     0%       35%       0%      1%   0%      1%     0%    0%     0%     30%(  1%)          0%        0%  22%      0%  14%  22%   5041   0%
  76%   68%   62%   52%   39%   23%   13%    9%    6%     5%     3%     3%     2%     2%     1%     1%     1%     0%     0%     0%  19%   8%  10%   6%   8%   8%   7%  10%   7%  11%   8%    7%    5%    7%    6%    5%   54%   50%   54%   52%   55%     0%       21%       0%      4%   0%     18%    15%    0%     0%     88%(  4%)        159%        0%  34%      0%  12%  20%   2109  97%                                                   
```


![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/6bc873c3-81e8-1622-049e-b26f742f4745.png)


## Waffinityについて

一方で、ドメイン単位における処理は分割単位が大きいため、Networkに関する処理やWAFLのデータ処理(全Aggregateをまとめて)するといったような大きな単位でしか処理を分割できず、マルチスレッド対応には限界がありましたが、現在ではより細かな単位で並列処理を可能にするためにWaffinityが導入されています
WAFLの処理内容ごとに階層的にマルチスレッド化を行うことで、より細かいレベルでの並列処理が可能になっています。

ざっくりと言いますと、以下のような形です。
・**ロック不要な範囲のユーザーファイルの読み書きを並列化**
・**データ構造やメタファイル変更操作（ファイル作成/削除など）を並列化**
・**別AggregateやVolume、ファイルブロック領域内の2つの操作などの分離データ操作を並列化**

物理CPU単位で分けるということではないので、正確な表現では無いですが、以下の図のようにVolume分けて、割り振られるIDが異なると処理も分けてくれるようなイメージを持っていただくと分かりやすいと思います。

<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/bfb6dac2-9a1c-f85b-86f9-231ba9264219.png>


**詳細を知りたい場合はアメリカのUSENIX協会へNetApp社のエンジニアが[論文寄稿](https://www.usenix.org/system/files/conference/osdi16/osdi16-curtis-maury.pdf)をしており、こちらに詳しく記載されております。**

内容が難しいので、Bing Chat等を活用して翻訳や要約をしながら読んで頂くと良いかと思いますが、以下の簡易図ように細かく処理をわける事で、ロックのかかってないものは並列で処理することで効率化を図ってます。
<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/a9e25748-a4f8-9565-0648-46084104a1a0.png>



## 1Volumeへのアクセスと4volumeへ分散した場合のパフォーマンスを比較してみる

以下のようなVolume数だけの違いでIOPSに差がでるか確認してみたいと思います。

<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/736d39b7-7c13-b181-922f-a7c4a191b4b8.png>


### 実施条件
・**検証とは別に既に負荷のかかっているFASで実施 (同じAggregateにVolume100個位)**
・**1Aggregateで1Volume作成か4 Volume作成かで同じアクセスパターンで差が出るか確認**
・CIFS環境で確認
・同じNetworkセグメントで確認
・Serverは4つの物理サーバを使用
・Volumeパターンに関係なく同じLIFへアクセス
・**重複排除や圧縮は有効化**
・**負荷をかけるツールはDISKSPDを使用**
　(Blockサイズ16Kで、60秒間Read/Writeの実施)


### 結果
以下のように、基本的には分散を図る事でIOPS等が増加しているのが確認できました。
1つめのVolumeは、既存環境の負荷影響なのか、リバランスの条件を満たしてない為なのか大きな増加はみられませんでした。

|  |Server#1 |Server#2   |Server#3   |Server#4  |
|---|---|---|---|---|
|**I/O per s(集約)**|4642|5081|4968|5017|
|<font color="Red">**I/O per s(分散)**</font>|4731|6501 |6585 |6505|
|**MiB/s(集約)**|72.54|79.4|77.63|78.4|
|<font color="Red">**MiB/s(分散)**</font>|73.92|101.58|102.89|101.65|
|**平均latency\[ms](集約)**|0.429|0.392|0.401|0.397|
|<font color="Red">**平均latency\[ms](分散)**</font>|0.421|0.307|0.303|0.306|

### 実際のDISKSPD出力
Server#4のDISKSPDの出力になりますが、以下の通りです。

#### 1volume集約時 
```bash:
> diskspd.exe -b16K -c1G -r -o1 -t2 -Sh -n -L -D -W0 -d60 -w50 \\172.16.10.149\share100\testfile4.dat

Command Line: diskspd.exe -b16K -c1G -r -o1 -t2 -Sh -n -L -D -W0 -d60 -w50 \\172.16.10.149\share100\testfile4.dat

Input parameters:

        timespan:   1
        -------------
        duration: 60s
        warm up time: 0s
        cool down time: 0s
        affinity disabled
        measuring latency
        gathering IOPS at intervals of 1000ms
        random seed: 0
        path: '\\172.16.10.149\share100\testfile4.dat'
                think time: 0ms
                burst size: 0
                software cache disabled
                hardware write cache disabled, writethrough on
                performing mix test (read/write ratio: 50/50)
                block size: 16KiB
                using random I/O (alignment: 16KiB)
                number of outstanding I/O operations per thread: 1
                threads per file: 2
                IO priority: normal

System information:

        computer name: PS-04
        start time: 2023/06/05 02:58:51 UTC

Results for timespan 1:
*******************************************************************************

actual test time:       60.00s
thread count:           2
proc count:             20

CPU |  Usage |  User  |  Kernel |  Idle
-------------------------------------------
   0|  45.76%|   0.10%|   45.65%|  54.24%
   1|   0.08%|   0.03%|    0.05%|  99.92%
   2|  10.81%|   0.70%|   10.11%|  89.19%
   3|   0.00%|   0.00%|    0.00%| 100.00%
   4|   7.08%|   0.42%|    6.67%|  92.92%
   5|   0.03%|   0.00%|    0.03%|  99.97%
   6|   0.34%|   0.10%|    0.23%|  99.66%
   7|   0.00%|   0.00%|    0.00%| 100.00%
   8|   0.10%|   0.03%|    0.08%|  99.90%
   9|   0.00%|   0.00%|    0.00%| 100.00%
  10|   4.95%|   0.00%|    4.95%|  95.05%
  11|   0.00%|   0.00%|    0.00%| 100.00%
  12|  20.78%|   0.00%|   20.78%|  79.22%
  13|   0.00%|   0.00%|    0.00%| 100.00%
  14|   0.08%|   0.00%|    0.08%|  99.92%
  15|   0.00%|   0.00%|    0.00%| 100.00%
  16|   0.03%|   0.03%|    0.00%|  99.97%
  17|   0.00%|   0.00%|    0.00%| 100.00%
  18|   0.03%|   0.00%|    0.03%|  99.97%
  19|   0.00%|   0.00%|    0.00%| 100.00%
-------------------------------------------
avg.|   4.50%|   0.07%|    4.43%|  95.50%

Total IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      2453602304 |       149756 |      39.00 |    2495.88 |    0.399 |     179.32 |     0.142 | \\172.16.10.149\share100\testfile4.dat (1GiB)
     1 |      2478817280 |       151295 |      39.40 |    2521.53 |    0.395 |     180.86 |     0.139 | \\172.16.10.149\share100\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        4932419584 |       301051 |      78.40 |    5017.41 |    0.397 |     359.78 |     0.141

Read IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      1231224832 |        75148 |      19.57 |    1252.44 |    0.375 |      92.95 |     0.141 | \\172.16.10.149\share100\testfile4.dat (1GiB)
     1 |      1241235456 |        75759 |      19.73 |    1262.62 |    0.370 |      91.07 |     0.137 | \\172.16.10.149\share100\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        2472460288 |       150907 |      39.30 |    2515.06 |    0.372 |     180.11 |     0.139

Write IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      1222377472 |        74608 |      19.43 |    1243.44 |    0.423 |      92.98 |     0.138 | \\172.16.10.149\share100\testfile4.dat (1GiB)
     1 |      1237581824 |        75536 |      19.67 |    1258.91 |    0.421 |      95.96 |     0.137 | \\172.16.10.149\share100\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        2459959296 |       150144 |      39.10 |    2502.35 |    0.422 |     186.39 |     0.137



total:
  %-ile |  Read (ms) | Write (ms) | Total (ms)
----------------------------------------------
    min |      0.217 |      0.249 |      0.217
   25th |      0.300 |      0.364 |      0.333
   50th |      0.354 |      0.404 |      0.382
   75th |      0.409 |      0.450 |      0.434
   90th |      0.477 |      0.504 |      0.493
   95th |      0.527 |      0.551 |      0.540
   99th |      0.729 |      0.760 |      0.745
3-nines |      2.232 |      2.275 |      2.246
4-nines |      3.548 |      3.881 |      3.765
5-nines |      4.775 |      4.988 |      4.775
6-nines |      5.664 |      5.955 |      5.955
7-nines |      5.664 |      5.955 |      5.955
8-nines |      5.664 |      5.955 |      5.955
9-nines |      5.664 |      5.955 |      5.955
    max |      5.664 |      5.955 |      5.955
             
```

#### 4volume分散時 

```bash:
> diskspd.exe -b16K -c1G -r -o1 -t2 -Sh -n -L -D -W0 -d60 -w50 \\172.16.10.149\share400\testfile4.dat

Command Line: diskspd.exe -b16K -c1G -r -o1 -t2 -Sh -n -L -D -W0 -d60 -w50 \\172.16.10.149\share400\testfile4.dat

Input parameters:

        timespan:   1
        -------------
        duration: 60s
        warm up time: 0s
        cool down time: 0s
        affinity disabled
        measuring latency
        gathering IOPS at intervals of 1000ms
        random seed: 0
        path: '\\172.16.10.149\share400\testfile4.dat'
                think time: 0ms
                burst size: 0
                software cache disabled
                hardware write cache disabled, writethrough on
                performing mix test (read/write ratio: 50/50)
                block size: 16KiB
                using random I/O (alignment: 16KiB)
                number of outstanding I/O operations per thread: 1
                threads per file: 2
                IO priority: normal

System information:

        computer name: PS-04
        start time: 2023/06/05 03:06:45 UTC

Results for timespan 1:
*******************************************************************************

actual test time:       60.00s
thread count:           2
proc count:             20

CPU |  Usage |  User  |  Kernel |  Idle
-------------------------------------------
   0|  44.87%|   0.00%|   44.87%|  55.13%
   1|   0.00%|   0.00%|    0.00%| 100.00%
   2|   0.03%|   0.00%|    0.03%|  99.97%
   3|   0.00%|   0.00%|    0.00%| 100.00%
   4|   0.16%|   0.05%|    0.10%|  99.84%
   5|   0.00%|   0.00%|    0.00%| 100.00%
   6|   0.03%|   0.00%|    0.03%|  99.97%
   7|   0.00%|   0.00%|    0.00%| 100.00%
   8|   0.05%|   0.03%|    0.03%|  99.95%
   9|   0.00%|   0.00%|    0.00%| 100.00%
  10|   1.80%|   0.03%|    1.77%|  98.20%
  11|   0.00%|   0.00%|    0.00%| 100.00%
  12|  25.23%|   0.13%|   25.10%|  74.77%
  13|   0.03%|   0.00%|    0.03%|  99.97%
  14|  11.09%|   0.29%|   10.81%|  88.91%
  15|   0.03%|   0.00%|    0.03%|  99.97%
  16|   7.32%|   0.29%|    7.03%|  92.68%
  17|   0.00%|   0.00%|    0.00%| 100.00%
  18|   0.49%|   0.00%|    0.49%|  99.51%
  19|   0.08%|   0.03%|    0.05%|  99.92%
-------------------------------------------
avg.|   4.56%|   0.04%|    4.52%|  95.44%

Total IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      3175841792 |       193838 |      50.48 |    3230.83 |    0.308 |     139.55 |     0.116 | \\172.16.10.149\share400\testfile4.dat (1GiB)
     1 |      3218964480 |       196470 |      51.17 |    3274.70 |    0.304 |     134.66 |     0.112 | \\172.16.10.149\share400\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        6394806272 |       390308 |     101.65 |    6505.53 |    0.306 |     273.21 |     0.114

Read IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      1591001088 |        97107 |      25.29 |    1618.55 |    0.281 |      76.18 |     0.114 | \\172.16.10.149\share400\testfile4.dat (1GiB)
     1 |      1609056256 |        98209 |      25.58 |    1636.92 |    0.275 |      71.87 |     0.110 | \\172.16.10.149\share400\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        3200057344 |       195316 |      50.87 |    3255.47 |    0.278 |     139.21 |     0.112

Write IO
thread |       bytes     |     I/Os     |    MiB/s   |  I/O per s |  AvgLat  | IopsStdDev | LatStdDev |  file
------------------------------------------------------------------------------------------------------------------
     0 |      1584840704 |        96731 |      25.19 |    1612.28 |    0.336 |      75.66 |     0.111 | \\172.16.10.149\share400\testfile4.dat (1GiB)
     1 |      1609908224 |        98261 |      25.59 |    1637.78 |    0.333 |      74.34 |     0.107 | \\172.16.10.149\share400\testfile4.dat (1GiB)
------------------------------------------------------------------------------------------------------------------
total:        3194748928 |       194992 |      50.78 |    3250.07 |    0.335 |     145.34 |     0.109



total:
  %-ile |  Read (ms) | Write (ms) | Total (ms)
----------------------------------------------
    min |      0.136 |      0.187 |      0.136
   25th |      0.211 |      0.280 |      0.242
   50th |      0.253 |      0.319 |      0.293
   75th |      0.316 |      0.367 |      0.348
   90th |      0.383 |      0.415 |      0.404
   95th |      0.439 |      0.450 |      0.446
   99th |      0.634 |      0.671 |      0.652
3-nines |      1.550 |      1.792 |      1.675
4-nines |      2.807 |      3.012 |      2.920
5-nines |      4.102 |      5.863 |      4.506
6-nines |      4.506 |      6.331 |      6.331
7-nines |      4.506 |      6.331 |      6.331
8-nines |      4.506 |      6.331 |      6.331
9-nines |      4.506 |      6.331 |      6.331
    max |      4.506 |      6.331 |      6.331
```

### FAQ
・Volumeは必ず4つじゃないとNG？
=> コントローラーのCPU搭載数で分散数(Waffinity ID)が変わってくるので、最小2個からと考えても良いと思います。(高スペックだと8個等)

・Volumeを複数作成しても負荷が偏ったらどうするの？
=> Affinity使用率に大きな偏りがあれば、自動的にVolumeのAffinity IDの割り当てを変更。
　(時間単位でチェックしているので、数分の検証では確認できないです)


## 参考及びリンク
[High latency from CPU even the CPU average utilization is not high](https://kb.netapp.com/onprem/ontap/hardware/High_latency_from_CPU_even_the_CPU_average_utilization_is_not_high)

[Lower than expected performance while utilizing a single volume](https://kb.netapp.com/onprem/ontap/Performance/Lower_than_expected_performance_while_utilizing_a_single_volume)

[CPU as a compute resource and the CPU domains explained in ONTAP 9](https://kb.netapp.com/onprem%2Fontap%2FPerformance%2FCPU_as_a_compute_resource_and_the_CPU_domains_explained_in_ONTAP_9)

[DISKSPD を使用してワークロード ストレージのパフォーマンスをテストする](https://learn.microsoft.com/ja-jp/azure-stack/hci/manage/diskspd-overview)

[To Waffinity and Beyond: A Scalable Architecture for Incremental Parallelization of File System Code](https://www.usenix.org/system/files/conference/osdi16/osdi16-curtis-maury.pdf)