IBM Cloud: veeamのICOSへの直接バックアップを試してみた

# はじめに
Veeem Backup & Replication (VBR) v12では、バックアップデータの保存先にオブジェクトストレージを直接指定することが可能となりました。

IBM CloudにはIBM Cloud Object Storage(ICOS)というサービスが存在しています。
今回はveeamのバックアップデータの保存先にICOSを直接指定した際、ICOSの費用算出に必要な以下項目について検証してみました。

・ICOSに保管されるファイルサイズとAPI実行回数
・バックアップ通信におけるブロックサイズ1MB（デフォルト設定）の場合と4MBの場合の差異


# 検証環境
IBM CloudのTOKYOリージョンのvpc環境で実施しています。
VBRのバージョンは12.2.0.334です。

【veeamサーバ】
・Virtual Servers for vpc
・OS : Windows Server 2022 Standard Edition (amd64)
・SPEC : bx2-4x16 (4vCPU, 16GiB, 8Gbps)
・NW Bandwidth : 6000Mbps

【バックアップ対象サーバ】
・Virtual Servers for vpc
・OS : Windows Server 2022 Standard Edition (amd64)
・SPEC : bx2-2x8 (2vCPU, 8GiB, 4Gbps)
・NW Bandwidth : 3000Mbps

# 検証内容
バックアップ世代数を3に設定したうえで、10GBの重しファイル（容量だけが目的で中身の無いファイル）を世代ごとにバックアップ対象サーバに追加(アクティブフルバックアップ取得後は削除)していきます。
重複排除や圧縮の結果、ICOSのファイルサイズ、API実行回数がどのように変動するかを確認します。
ブロックサイズ1MBの場合、4MBの場合ともに同様の手順で検証を行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/380e749a-a86c-4bcb-a9bf-dc2af95d46de.png)



#### 1世代目 : フルバックアップ
・ディスク使用量21.1GB/99.8GBのバックアップ対象サーバの初回フルバックアップを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/97626608-0619-f10c-6f34-5f8df2c4f401.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/049bdd4d-b6c1-d1c4-a218-e19a1a714adb.png)

#### 2~7世代目 : 差分バックアップ
・10GBの重しファイルを追加しつつ都度差分バックアップを取得します。

【重しファイル作成方法】
1\. PowerShellを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/98bd5778-a414-0eef-71be-bdbcff1a47a8.png)

2\. 重しファイルを作成するフォルダ(今回はBackupTest)に移動します。
```rb
cd C:\BackupTest\
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/9e4c92c8-8b01-49b0-943b-beb0f4d51a20.png)



3\. 下記スクリプトを実行します。
```rb
function Make-RandomFile ([Parameter(Mandatory=$true)][string]$OutPath, [Parameter(Mandatory=$true)][long]$FileSize, [int]$ChunkSize = 16MB) {
    $bin1 = [byte[]]::new($ChunkSize);
    $bin2 = [byte[]]::new($ChunkSize);
    $r = [System.Random]::new();
    [long]$progress = 0;
    [int]$nextLen = 0;
    $fs = [System.IO.File]::Create([System.IO.Path]::Combine($PWD, $OutPath));
    try {
        do {
            $task = $fs.WriteAsync($bin1, 0, $nextLen);
            $r.NextBytes($bin2);
            $task.Wait();
            $bin1, $bin2 = $bin2, $bin1;
            $progress += $nextLen;
            $nextLen = [System.Math]::Min([long]$ChunkSize, $FileSize - $progress);
        } while ($nextLen -gt 0);
    } finally {
        $fs.Dispose();
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/eb3fa485-0223-9d9a-8c1a-1a0a2500c23f.png)


上記スクリプトはこちらを参照させていただきました。

https://aquasoftware.net/blog/?p=1816


4\. 下記コマンドを順番に実行します。(今回は10GBずつ重し追加のため1世代につき2行ずつ実行)
```rb
Make-RandomFile .\out5G-01.bin -FileSize 5GB;
Make-RandomFile .\out5G-02.bin -FileSize 5GB;
Make-RandomFile .\out5G-03.bin -FileSize 5GB;
Make-RandomFile .\out5G-04.bin -FileSize 5GB;
Make-RandomFile .\out5G-05.bin -FileSize 5GB;
Make-RandomFile .\out5G-06.bin -FileSize 5GB;
Make-RandomFile .\out5G-07.bin -FileSize 5GB;
Make-RandomFile .\out5G-08.bin -FileSize 5GB;
Make-RandomFile .\out5G-09.bin -FileSize 5GB;
Make-RandomFile .\out5G-10.bin -FileSize 5GB;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/c0674e5c-aeda-0ed3-231a-713eb744eb19.png)
・重しファイルの作成が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/62883fee-7a42-d194-d1b5-071ddc50f41a.png)
・差分バックアップを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/e33f5539-9ae1-0639-dcd2-bbc96c97aa63.png)

#### 8世代目 : アクティブフルバックアップ
・今回はジョブを定期的に実行するようスケジュールを指定していないため、フルバックアップも手動で実行します。
(ジョブスケジュールの指定がなくとも、3世代超えたところで自動的にフルバックアップは取得されるものと勘違いしていたため、今回8世代目までフルバックアップなしで進めてしまいました。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/1b27ac8f-36be-b653-225c-0bc2ac85c9c2.png)

#### 9世代目 : 差分バックアップ
・10GBの重しファイルを削除し、差分バックアップを取得します。
・フルバックアップ後ですが、3世代前の状態に戻すためには初回フルバックアップからの差分が必要であるため、このタイミングで差分ファイルは何も削除されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/77639d46-a0c3-f7e7-4c31-bb3e240b8f26.png)


#### 10世代目 : 差分バックアップ
・10GBの重しファイルを削除し、差分バックアップを取得します。
・3世代前がアクティブフルバックアップのため、それ以前のバックアップは不要になり削除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/fe2038a2-9243-8fd8-108f-565958373ba4.png)


#### 11世代目 : 差分バックアップ
・10GBの重しファイルを削除し、差分バックアップを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/a05ffed9-c38d-b23b-8bf0-aeb014b31f2f.png)

# 検証結果
### 1) ICOS保管ファイルサイズ 
1MBの場合
・757.65GB（各世代で保管された容量を足し合わせたもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/bcaefd3c-e809-4b08-99b7-4e62f1a302e6.png)

4MBの場合
・838.63GB
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/cbba1096-41cd-472a-9f37-69ce74e2eec7.png)

#### ICOS保管ファイルサイズまとめ
・ブロックサイズ1MBの場合も4MBの場合も、ICOSに保管されるファイルサイズに大きな差はありませんでした。

:::note warn
4MBの10世代目で不要な差分ファイルが削除されファイルサイズが小さくなる想定だったのですが（設定世代数3のため）、今回の検証では11世代目で削除されたように見えており、「もしかしてICOSに大量にDelete要求が来るとサービス全体状況によっては後回しで削除するのか、、？」と予想していますが、真偽不明です。
理由ご存知の方いらっしゃいましたらコメントいただけますと大変有り難いです、、！
:::


### 2)API総実行回数
1MBの場合
・クラスA（書き込みAPI）：185,190回
・クラスB（読み取りAPI）：13,728回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/840496fb-6683-4765-a977-2827ccdada51.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/40f43662-c857-49b3-bf65-a9a244601d9e.png)


4MBの場合
・クラスA：54,083回
・クラスB：13,364回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/ad5ec0d4-5332-46a6-bb0f-f381a0e73556.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/44d5326e-828e-4065-9cad-9e4f6d5eabef.png)

#### API総実行回数まとめ
・クラスA実行回数：ブロックサイズ4MBにすると、1MBの場合と比較して**約71%減少**しました。　
　{(185,190-54,083)/185,190×100=70.7959...}
・クラスB実行回数：ブロックサイズ1MBでも4MBでもほぼ同じでした。

### 3)ジョブ処理時間
1MBの場合
・139分（各世代での処理時間を足し合わせたもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/6e9ce372-677a-449d-acc1-247a5efd1765.png)

4MBの場合
・158分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966142/dfe40ea6-98c5-4a62-a0bc-389937a262d3.png)

#### ジョブ処理時間まとめ
・ブロックサイズ4MBの場合、1MBと比較して処理時間は**約14%増加**の結果になりました。
　{(158-139)/139×100=13.6690...}

# さいごに
今回の検証では、ブロックサイズ1MBでも4MBでもICOS上のファイルサイズは大きく変わらないなか、4MBの場合はクラスAのAPI実行回数が1/3程度にまで減少するという結果になりました。
バックアップ対象のファイルサイズが大きくなると、よりこの差の影響は大きくなると考えられます。
ジョブ処理時間が多少長くなるというデメリットはあるものの、例えばICOSは保管容量の他にAPI実行回数も課金対象になっているため、ブロックサイズを4MBに変更することでオブジェクトストレージコストの最適化ができるケースもありそうです。
環境によって結果が変わる可能性はありますが、1つの目安として参考になれば幸いです。

最後までお読みいただき、ありがとうございました！