S3互換MinIOサーバーを１年運用した所感

この記事は <a href="https://qiita.com/advent-calendar/2023/dena-24-newgrad">DeNA 24 新卒 Advent Calendar 2023</a>の14日目の記事です。

NAS代わりに実際に使用しているMinIOサーバーについて特徴や運用の感想を書きました。

おそらくS3のローカル版としてDockerに入れた事がある人もいるかと思います。今回はこれを本格的にストレージサーバーとして運用した所感について報告します。

私の計画としては低信頼の激安中古HDDと冗長性のためのイレイジャーコーディング技術を組み合わせて可能な限り安く安定的なストレージを獲得するといった方向になります。

## MinIOとは
Amazon S3互換のオープンソースオブジェクトストレージシステムです。これを使うことでAWSのS3サーバーと同様にS3APIでファイルをホストできます。

## オブジェクトストレージの特徴

クラウドで使われるストレージとしてよく用いられるオブジェクトストレージ（普通のファイルストレージとの違いについては以下の記事を参照

https://aws.amazon.com/jp/compare/the-difference-between-block-file-object-storage/

内容を簡単にまとめると耐障害性に優れており、なにより安価な方式です。

MinIOでは耐障害性のためにイレイジャーコーディングという技術と筐体をまたいだストレージ構築を利用しています。

## イレイジャーコーディングについて

イレイジャーコーディング（Erasure Coding）はデータを冗長性を含む形式に変換する技術です。データを分割してパリティーを別々に保存することで複数台のディスクが壊れてもデータが復旧できます。データを6つのデータと２つのパリティーの合計８つの同じサイズのデータにして、すべて別々のハードディスクに保存することでたとえ２台が壊れても維持できるようになっています。

## RAID5,6との違い

さて、このパリティーにして保存という考え方ですがピンときた方もいるかもしれません、すでにRAID5,6で使われていることを。確かに考え方は同じですが上限が異なります。32本のハードディスクを使ってRAIDとイレイジャーコーディングでの利用効率の評価をします。

| 方式 | 利用可能容量（％） | 障害耐性（台） | 説明 |
|:-:|:-:|:-:|:-:|
| RAID0  |  100% |  0 |  32台のHDDをそのまま連結させる。全容量が利用できるが１台でも壊れるとデータを失う |
| RAID5  | 97%  |  1 | 1台まで壊れても大丈夫  |
| RAID6  | 93% | 2  | 2台まで壊れても大丈夫 |
| EC:1  |  93%   | 2  |2台まで壊れても大丈夫 イレイジャーコーディングではパリティーの数は可変  |
| EC:2  |  87%   | 4  |4台まで壊れても大丈夫  |
| EC:3  |  81%   | 6  |6台まで壊れても大丈夫  |
| EC:4  |  75%   | 8  |8台まで壊れても大丈夫  |
| EC:5  |  68%   | 10  |10台まで壊れても大丈夫  |
| EC:6  |  62%   | 12  |12台まで壊れても大丈夫  |
| EC:7  |  56%   | 14  |14台まで壊れても大丈夫  |
| EC:8  |  50%   | 16  |16台まで壊れても大丈夫　上限は半分までなのでこれ以上は冗長性を高められない  |

表からわかるメリットとしては大規模なデータを扱うときに高い可用性のオプションが豊富なことでしょう。RAIDではディスクの耐障害性を50%にした上で利用可能容量を50%にすることができない計算です。
他にも見逃せない違いとしてRAIDの場合1台が壊れて新しいディスクを入れて再構成(リビルド)が完了する間アクセスできないのに対して、MinIOではリビルド中（MinIOではヒールと言います）にも読み書きが可能です。高可用性、耐障害性に優れていると言うだけはありますね。

# 実際のデータの流れ
これまで性質の説明をしたところで、どのようにして実現するのか見てみましょう。

<https://github.com/minio/minio/tree/master/docs/distributed#expanding-existing-distributed-setup>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/5f4180e3-ef66-8bde-5a73-4017bf6aedcb.png)

上の画像は4個のサーバーがそれぞれ２台のハードディスクを持っているときのファイル保存動作の様子です。[^1]

* 何らかのアプリケーションがファイルをバケットに保存するS3APIを2つ発行すると前段のロードバランサーによってサーバーにリクエストを振り分けます。例ではサーバー２とサーバー３に振り分けられました
* Object1について追跡するとサーバー２がファイルを6個のデータと2つのパリティーに分割している
* それを自分の手持ちのハードディスクをと他のサーバーに送信し、保存させている
* Object2についても同様

筐体をまたいだストレージの構築はこのように行われていました。



# 運用してみた
![minio1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/6903a0fe-91a2-ecfd-bc2f-39ad67614934.png)


<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/985c8492-3b7b-d660-13cb-82f375e7eafc.png">


4台のminioサーバーをproxmoxの中に仮想サーバーで用意しました。proxmoxのパススルー機能でそれぞれのサーバーに2台ずつハードディスクを接続しています。
作ったサーバーに対してnginxでhttps接続とロードバランシングを設定して外部から安全に接続できるようにしました。
また、prometheusに統計情報を送信し、grafanaで可視化もしました



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/de6c1921-5385-9d77-7035-193b329c8eb9.png)

ダッシュボードの画像

## メンテナンス
定期的にCLIツールのminio clientでアップデートを行います。また故障しているハードディスクがないかオフラインディスクをチェックします。これもCLIクライアントでできます。
```
#アップデート 無停止でやってくれる
 ./mc.exe admin update myminio
minioServer `minio` updated successfully from 2023-11-11T08:14:41Z to 2023-12-02T10-51-33Z
#ディスクの確認
./mc.exe admin info myminio
●  minionode0:9000
   Uptime: 2 minutes
   Version: 2023-12-02T10:51:33Z
   Network: 4/4 OK
   Drives: 2/2 OK
   Pool: 1

●  minionode1:9000
   Uptime: 2 minutes
   Version: 2023-12-02T10:51:33Z
   Network: 4/4 OK
   Drives: 2/2 OK
   Pool: 1

●  minionode2:9000
   Uptime: 2 minutes
   Version: 2023-12-02T10:51:33Z
   Network: 4/4 OK
   Drives: 2/2 OK
   Pool: 1

●  minionode3:9000
   Uptime: 2 minutes
   Version: 2023-12-02T10:51:33Z
   Network: 4/4 OK
   Drives: 2/2 OK
   Pool: 1

Pools:
   1st, Erasure sets: 1, Drives per erasure set: 8

1.4 TiB Used, 10 Buckets, 56,523 Objects, 578 Versions
8 drives online, 0 drives offline
 
```
## 故障したハードディスクの交換

運用10ヶ月目でハードディスクが１台壊れました。そのため交換を行いました。手順としては自動マウントのIDを新しいIDに書き換えるのと、新しいハードディスクのフォーマットしたのち管轄のサーバーを再起動するだけでした。

## 復旧時のメトリクス
復旧するまでのメトリクスが取れたのでせっかくなのでgrafanaで可視化したものを記録として貼っておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/069800c1-91b8-0936-c906-711842bfb75a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/55feb843-a1f1-0fc1-b78a-6507b3f1007c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308674/a39dfbdc-8071-76b4-b40c-6ff72d3ca1a3.png)

午前2時に設定が完了、5分以内に自動修復が開始
午前6時にメインPCの定期バックアップが開始
午前6時10分にメインPCの定期バックアップ終了(メインPCのログより確認)
午前6時27分に修復完了

結果、修復中に200GB程度のデータを受け取っても普段通りの速さで処理できていたことが分かりました。


## 使って感じたメリット


* ヒーリング中にアップロード、ダウンロード共に可能なところ。可用性に関してよく考えられていると思いました。
* アップデートが楽。設定さえすればアップデートコマンド一発で完了する。またアップデート時のダウンタイムが1秒未満ととても早い(ローリングアップデートではなくすべてのサーバーがアップデートをダウンロード、展開完了後に一斉にアップデートする仕組みのため、サーバーが100000台といったローリングアップデートではアップデート頻度に間に合わない規模でもそこまで影響がなさそうです)。
* 安い。サーバーとHDD含めて6万円で20TB(物理容量32TB)の冗長化されたディスクが手に入りました。
* 十分な速度が出ます。ボトルネックはネットワークの速度でした。



## 知っておいてほしいこと　デメリットについて
* MinIOは容量の追加ができません。最初に設定した容量から増やすことが基本的にできません[^2]
* すべてのディスクの容量を揃える必要があります。例えば7台が8TBで1台が1TBの場合　8台のディスクが全て1TBとして扱われます。
* メモリを使います。イレイジャーコーディングを有効にするには最低４台のサーバーが必要です。メモリはサーバーあたり1.5Gbほどでうまく動いてくれていますが合計すると馬鹿になりません。(仮想マシンじゃなくてlxcにしとけばよかったという後悔)
* 100TB以上になるとお金がかかります。無料ライセンスでは100TBまでで、超えるとライセンスを買う必要があります。
* ごくまれに数分間Webコンソールだけにアクセスできないことがあり、原因を調べたが不明だった。ネットで探しても同じ症状の人がいても解決策は見つからないのでS3を扱える他のツールを併用しておくほうが良いです。

# 感想


　minioはdockerでしか使ったことがなかったのですが本格的な運用もアリだと思いました（そもそもそっちの用途がメインで開発されたわけですが）。minioの性質としては可用性とコストに特化してるように感じました。特にローリングアップデートをしないところやヒーリング中に書き込み可能な点は特徴的だと感じました。
 



[^1]: サーバーの数がnと書いてありますがわかりやすさのため4にしました
[^2]: 一応できますがhttps://github.com/minio/minio/tree/master/docs/distributed#expanding-existing-distributed-setup 同じ規模のものを用意する必要があるため柔軟性は低いです