ElementOSとONTAPにおける容量効率の違い

# はじめに
**ElementOS(旧名Solidfire)は**2023年10月に販売が既に終了しておりますが、**2028年10月までのサポートが保証されています。
とは言うものの、サポート終了までに別の機器への移行の準備が必要**となってきますが、仮にAFF機器（ONTAP）への移行を考える際でも、ElementOSのClusterをONTAP SAN構成のClusterの1:1で移行できるのか、集約できそうか、NAS利用の方が良いのかといった**データ移行容量の見積もりは不可欠**かと思います。

ElementOSとONTAPのどちらも、Efficiency機能として重複排除や圧縮機能を利用できますが、**ONTAP独自の[Sequential packing](https://docs.netapp.com/ja-jp/ontap/volumes/enable-temperature-sensitive-efficiency-concept.html)や[Inline Data Compaction](https://docs.netapp.com/ja-jp/ontap/volumes/manage-inline-data-compaction-aff-task.html)機能の恩恵をどれだけ受けられる**か、効率的な容量計画が求められます。
特に、**SANでは無くNAS環境への移行を検討する場合、ファイル数が多いとWAFLの特性により移行先のONTAPに必要となる容量の増加**が考えられます。

本記事では、ファイル数の多い環境におけるSANとNASの容量効率に注目した差異について記載致します。


<img width="450" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/5ddb087c-c17c-4d5b-94bb-f92526eaa07d.png>



## 何をしたい？できる？
重複排除や圧縮の効きやすいファイルを計100万ファイル程度用意して容量差を比較
<font color="Red">**ElementOSからONTAPのSAN環境へ移行した際のEfficiency値の違い**</font>
**ElementOSからONTAPのNAS環境へ移行した際のEfficiency値の違い**

## Efficiency機能の差異について
OSによる機能の差異については、以下の通りですが、Element OSにおいてはSSDに書き込みの際に、以下のような形で実施となるのでCompactionに近い動作となっています。

1. 書き込みを4Kに分断
2. インライン圧縮
3. NVRAMにWrite
4. NVRAMからSSDへWrite時に重複排除
(NVRAM上のデータは1MBにまとめた単位で任意のNoedのSSDへ書き込み)

| OS| 重複排除＋圧縮 | Sequential packing | Compaction |Effciency単位|
| --- | --- | --- | --- | --- |
| **ElementOS** | 〇| × | 〇※(類似)  | Cluster |
| **ONTAP(AFF)** | 〇 | 〇 | 〇 | Aggregate |




**Sequential packingは**、ONTAP内で32KB単位の圧縮を実施した際に、**連続する物理ブロックを効率的に圧縮**し、デバイスへ保存する機能となります。(以前は圧縮グループが異なるものは同じブロックにはならなかった)

<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/24855184-1fb0-426a-a9f2-9ff7c9c8f695.png>

**Inline Data Compactionは**、ONTAPでは通常４KB単位でデータが格納されるが、**4KB以下のデータを纏めて格納する事で容量の効率化を実現する機能**となります。

<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/b3bf3d91-2b8e-4fe8-b615-717b5c47b84e.png>



## 記事における環境情報
本記事では、以下の環境で実施した内容となります。
- Windows Client
- NetApp HCI :ElementOS 12.3
- Netapp FAS :ONTAP 9.14.1(Efficiency未設定)
- Netapp AFF: ONTAP 9.16.1

環境のイメージとしては以下の通りです。


<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/329dfe53-4170-49d9-8c71-54f7e874d349.png>


## 実施手順


### 1. 書き込み用ファイルの作成
ファイル数の多い環境を用意する為、以下のようなTextファイルを用意します。
| サイズ| ファイル個数 | 
| --- | --- |
| 約10MB | 100| 
| 約1MB | 1,000 |
| 約100KB | 10,000 |
| 約10KB | 100,000 |
| 約1KB | 1,000,000 |

<img width="450" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/3e287909-5b81-4e20-aff3-7d10c6cb1dae.png>


#### 1-1. Pythonでファイル作成スクリプトの用意

ファイル作成にあたって、以下のような機能を持つスクリプトを使用して実施しています。

<font color="Blue">　・作成されるファイルの最小サイズは1KB
　・テキストファイルの中身は"Certainly! A Wizard's (省略)"という文字列を1KB分記載 
　・文字列の最後に1～20のいずれかの数字を付与 
　・ファイル内の60行ごとに同じ数字を指定※
　・ファイルサイズを指定可能 
　・フォルダ数とその中に作成するファイル数を指定可能 
　・ファイル名やフォルダ名は作成された数を名前とする </font>


※同じテキスト行だけを繰り返すと、重複排除と圧縮の効果が高くなりすぎるので、英文の後ろに数字を付与して、60行単位で数字が変わるようにしています。


```bash:
import os
import random


def create_text_files(base_path, folder_count, files_per_folder, min_size_kb):
    # 定数定義
    base_string = "Certainly! A Wizard's Job is to vex Chumps quickly in foggy moors."
    
    # 最小サイズをバイト単位に変換
    min_size_bytes = min_size_kb * 1024
    
    # ベースパスの存在を確認し、存在しなければ作成
    if not os.path.exists(base_path):
        os.makedirs(base_path)
    
    # フォルダとファイルを作成
    for folder_num in range(1, folder_count + 1):
        folder_name = os.path.join(base_path, f"folder_{folder_num}")
        os.makedirs(folder_name, exist_ok=True)
        
        for file_num in range(1, files_per_folder + 1):
            file_name = os.path.join(folder_name, f"file_{file_num}.txt")
            with open(file_name, 'w') as file:
                bytes_written = 0
                line_count = 0  # 行数をカウントする変数
                random_number = random.randint(1, 20)  # 最初のランダムな数字を生成
                while bytes_written < min_size_bytes:
                    # 60行ごとにランダムな数字を更新
                    if line_count % 60 == 0:
                        random_number = random.randint(1, 20)
                    
                    # 文字列と行単位のランダムな数字を付与して改行
                    line = f"{base_string}{random_number}\n"
                    file.write(line)
                    bytes_written += len(line.encode('utf-8'))  # 書き込んだバイト数を更新
                    line_count += 1  # 行数をインクリメント


def main():
    # ユーザー入力
    print("")
    base_path = input("ファイルを作成する基準となるパスを入力してください: ")
    folder_count = int(input("作成するフォルダ数を入力してください: "))
    files_per_folder = int(input("各フォルダに作成するファイル数を入力してください: "))
    min_size_kb = int(input("作成するファイルの最小サイズ(KB)を入力してください: "))
    print("")
    
    # テキストファイル作成
    create_text_files(base_path, folder_count, files_per_folder, min_size_kb)
    print("ファイルの作成が完了しました。")


if __name__ == "__main__":
    main()

```

スクリプトを実行しパスやファイルサイズ、作成数を入力すると以下のような形でファイル作成を実施できます。
```bat:
> python filemake.py

ファイルを作成する基準となるパスを入力してください: C:\dummy\test
作成するフォルダ数を入力してください: 1
各フォルダに作成するファイル数を入力してください: 10
作成するファイルの最小サイズ(KB)を入力してください: 100

ファイルの作成が完了しました。
```
作成されたファイルの中身は、60行単位で同じ文字列の最後に同じ数字を付け加えるようになっています。


<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/29f3db23-4483-42b2-a22f-ea177a85a62f.png>


<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/8e7cfa28-f71e-4b9c-9d10-349fceb273e9.png>


### 2. ONTAP側でColdデータ閾値の調整
ONTAPでは、デフォルトで14日間触られていないデータをColdデータとして扱い32KB単位で再圧縮し、合わせてSequential packingが実施されるので、コールドデータとしての扱いを最短の1日に変更します。
(検証なので、待ち時間を減らしたい)

```bash:
# Advanceモードに変更
> set advanced

Warning: These advanced commands are potentially dangerous; use them only when directed to do so by NetApp personnel.
Do you want to continue? {y|n}: y

#　データをCold扱いとする閾値の変更
> run -node * options tsse.auto_scan_cold_days 1

> run -node * options tsse.auto_scan_cold_days 
2 entries were acted on.

Node: PS-C250-01
tsse.auto_scan_cold_days     1          (value might be overwritten in takeover)

Node: PS-C250-02
tsse.auto_scan_cold_days     1          (value might be overwritten in takeover)

#Coldデータの再圧縮Scanに対する閾値変更
*> volume efficiency inactive-data-compression modify -vserver iscsi02 -volume vol200 -threshold-days 1 -threshold-days-max 1 -threshold-days-min 1
```

### 3. ファイルの書き込み
Element OS及びONTAPに同じデータの書き込みを実施します。
ONTAP側では、[iSCSI環境](https://qiita.com/s_yosh1d/items/b2ca28c542dfa6df0629)のような形で環境を構成してFileの書き込みを実施しています。

<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/4fd6f588-472e-48ee-b7d2-a1c84640b04a.png>



### 4. SAN環境における物理ブロック使用量の差

まず、結果として以下の表のような形となってます。
Element OSはHelix Data Protectionによる二重書き(Mirror)とはいえ、かなりEfficiency効果が高い点を確認できますが、Effiiency機能を使用したSAN構成のONTAPではElement OSと同じ物理容量を用意すると集約できそうな事が確認できます。

| Storage OS| 物理ブロック使用量 |  データ冗長化 | 
| --- | --- |  --- | 
| **ONTAP(Efficiency無効で基準値)** | 9.4GB | RAID DP | 
| **ElementOS(Efficiency有効)** | 2.4GB| Helix Data Protection | 
| **ONTAP(AFFでEfficiency有効)** | 1.49GB | RAID DP  | 


#### 4-1. ONTAP (Efficiency無効で基準値) の使用量の変遷

重複排除や圧縮を利用しないiSCSI環境でどの程度ブロックが消費されるか確認します。
1Kといった細かいファイルが多いので、Widowsのプロパティで表示された7.8GB以上消費される事が確認できます。
(ONTAPは4K単位のBlockなので、1Kファイルでも4K消費されてしまう)

```bash:
# 書き込み前のAggregateの使用率 
> df -A -h node2_aggr1
Aggregate                total       used      avail capacity
node2_aggr1             3780GB     4567MB     3775GB       0%
node2_aggr1/.snapshot       0B         0B         0B       0%
2 entries were displayed.

# 書き込み前のVolumeの使用率 
> df -h -vserver iscsi01 -volume vol100
Filesystem               total       used      avail capacity  Mounted on
/vol/vol100/              52GB       88MB       52GB       0%  ---
/vol/vol100/.snapshot   2816MB         0B     2816MB       0%  ---
2 entries were displayed

# Efficiency無効である事の確認
> volume efficiency show -vserver iscsi01
There are no entries matching your query.



# 書き込み後のAggregateの使用率 
> df -A -m node2_aggr1
Aggregate                total       used      avail capacity
node2_aggr1          3870915MB    14220MB  3856694MB       0%
node2_aggr1/.snapshot      0MB        0MB        0MB       0%

# 書き込み後のVolumeの使用率 
> df -h -vserver iscsi01 -volume vol100
Filesystem               total       used      avail capacity  Mounted on
/vol/vol100/              52GB     9570MB       42GB      17%  ---
/vol/vol100/.snapshot   2816MB         0B     2816MB       0%  ---
2 entries were displayed.
```

#### 4-2. ElementOS (Efficiency有効) の使用量の変遷

Element OSはHelix Data Protection(2重書き)とはいえ、効率的なEfficiencyが実施されている点が確認できます。

**書き込み前の使用率**
<img width="400" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/29a3b385-1a9d-40f6-a334-ff2f4f9a87d2.png>


**書き込み後の使用率** 
<img width="400" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/f7f28382-7563-4d1d-b1b4-5d706c0edeb2.png>


#### 4-3. ONTAP (AFFでEfficiency有効)  の使用量の変遷
書き込み後のデータをColdデータして再圧縮を実施させる為、書き込み後1日置いて確認しています。
Volumeとしては、重複排除+圧縮後の値であるで約2.6GBの消費となっていますが、Aggregate上ではSequential packingやInline Data Compactionが機能しているので、より消費量が少なくなっている点が確認できます。

```bash:
# 書き込み前のAggregateの使用率 
> df -A -h aggr1_node2
Aggregate                total       used      avail capacity
aggr1_node2               24TB     7861MB       24TB       0%
aggr1_node2/.snapshot       0B         0B         0B       0%
2 entries were displayed.

# 書き込み前のVolumeの使用率 
> df -h  -vserver iscsi02 -volume vol200
Filesystem               total       used      avail capacity  Mounted on
/vol/vol200/              52GB     4212KB       52GB       0%  /vol200
/vol/vol200/.snapshot   2816MB         0B     2816MB       0%  /vol200/.snapshot
2 entries were displayed.


# Efficiencyが有効である事の確認
> volume efficiency show -vserver iscsi02
Vserver    Volume           State     Status      Progress           Policy
---------- ---------------- --------- ----------- ------------------ ----------
iscsi02    vol200           Enabled   Idle        Idle for 29:15:18  auto


# 書き込み後のAggregateの使用率 
>  df -m -A aggr1_node2
Aggregate                total       used      avail capacity
aggr1_node2         26199342MB     9387MB 26189954MB       0%
aggr1_node2/.snapshot      0MB        0MB        0MB       0%
2 entries were displayed.


# 書き込み後のVolumeの使用率 
> df -h  -vserver iscsi02 -volume vol200
Filesystem               total       used      avail capacity  Mounted on
/vol/vol200/              52GB     2721MB       49GB       5%  /vol200
/vol/vol200/.snapshot   2816MB         0B     2816MB       0%  /vol200/.snapshot
2 entries were displayed.
```


### (参考)NAS環境における物理ブロック使用量の差

NASで同等のファイルを書き込むと以下のような値となります。

| Storage OS| 物理ブロック使用量 |  プロトコル | 
| --- | --- |  --- | 
| **ONTAP(AFFでEfficiency有効)** | 1.49GB | SAN  |
| **ONTAP(AFFでEfficiency有効)** | 4.9GB | NAS  |

```bash:
# 書き込み前のAggregateの使用率 
> df -A -h aggr1_node2
Aggregate                total       used      avail capacity
aggr1_node2         26199342MB     7832MB 26191509MB       0%
aggr1_node2/.snapshot      0MB        0MB        0MB       0%
2 entries were displayed.

# 書き込み前のVolumeの使用率 
> df -h  -vserver iscsi02 -volume vol200
Filesystem               total       used      avail capacity  Mounted on                 Vserver
/vol/vol200/              47GB      348KB       47GB       0%  /vol200                    cifs02
/vol/vol200/.snapshot   2560MB         0B     2560MB       0%  /vol200/.snapshot          cifs02
2 entries were displayed.



# Efficiencyが有効である事の確認
> volume efficiency show -vserver cifs02
Vserver    Volume           State     Status      Progress           Policy
---------- ---------------- --------- ----------- ------------------ ----------
cifs02     vol200           Enabled   Idle        Idle for 14:46:37  auto



# 書き込み後のAggregateの使用率 
>  df -m -A aggr1_node2
Aggregate                total       used      avail capacity
aggr1_node2         26199342MB    12918MB 26186423MB       0%
aggr1_node2/.snapshot      0MB        0MB        0MB       0%
2 entries were displayed.


# 書き込み後のVolumeの使用率 
> df -h  -vserver cifs02 -volume vol200
Filesystem               total       used      avail capacity  Mounted on
/vol/vol200/              47GB     4564MB       43GB       9%  /vol200
/vol/vol200/.snapshot   2560MB         0B     2560MB       0%  /vol200/.snapshot
2 entries were displayed.
```

本記事のSAN環境ではWindowsのiSCSI環境となるのでNTFSでフォーマットされますが、NTFSではMFT(Master File Table)という仕組みで管理される為、各ファイルのレコードが1KBとなります。
つまり、SAN環境でLUNを作成すると4KBのBlockに各ファイルのレコードが集約するようなイメージとなります。
<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/7a6fd322-ddeb-4639-958c-675739c145db.png>



一方、ONTAPではBlockの単位が4KB単位で、NAS環境で1ファイル作成するとiNodeで4KB消費される形になりますので、特に小さいファイルが大量にある環境の場合、MetaData + Dataが大量に作成される形になり、容量効率がSAN環境ほど期待できなくなります。
WAFLについては[wiki](https://en.wikipedia.org/wiki/Write_Anywhere_File_Layout)や[論文](https://www.usenix.org/legacy/events/usenix08/tech/full_papers/edwards/edwards.pdf)で構成について詳しく確認できます。
<img width="700" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/59a876b5-4fd7-4fa0-9c0b-404eb45fbc4d.png>




## 参考及びリンク
[【今から覚えるONTAPの操作】iSCSI用のSVMを作成する](https://qiita.com/s_yosh1d/items/b2ca28c542dfa6df0629)

[Element Software Delivers Data Efficiencies to Reduce Costs](https://www.netapp.com/media/16943-sb-3940.pdf)

[ONTAP storage efficiency overview](https://docs.netapp.com/us-en/ontap/concepts/storage-efficiency-overview.html)

[Temperature-sensitive storage efficiency overview](https://docs.netapp.com/us-en/ontap/volumes/enable-temperature-sensitive-efficiency-concept.html)

[How to verify TSSE-related options](https://kb.netapp.com/on-prem%2Fontap%2FOntap_OS%2FOS-KBs%2FHow_to_verify_TSSE-related_options)