AWSのMulti-Attach EBS Volumesが「共有ストレージ」に使えるか検証してみた

**2/19: 検証の結果、詳しいことが分かり、進捗を受けて記事タイトルを改題しています。[公式サイト](https://aws.amazon.com/jp/blogs/aws/new-multi-attach-for-provisioned-iops-io1-amazon-ebs-volumes/)の記事にあるIMPORTANT SAFETY TIPSがまさに記事中の事象を表していることが分かり、追記しました。**
※ 旧タイトル「AWSのMulti-Attach EBS VolumesをWindows Serverで使うと、EBSの容量が実質2倍になる？」

# はじめに
2020/2/14のAWSアップデートで、プロビジョンドIOPS (io1) のEBSボリュームに限り、複数EC2から同時アタッチできるようになりました。

これだけを見ると、いかにも「**共有ストレージ**」 (後述の図のような構成) に使えそうだと思えてきます。

**New – Multi-Attach for Provisioned IOPS (io1) Amazon EBS Volumes**
https://aws.amazon.com/jp/blogs/aws/new-multi-attach-for-provisioned-iops-io1-amazon-ebs-volumes/

このアップデートを聞いて、Windows Server 2019 で共有ストレージを組んでみようと思い、検証してみました。

**検証の結果ですが、Windows Server 2019の標準機能では共有ストレージとしては使えないようです。**
**以下で示す検証結果は「実施してはいけない行為」の好例となります。**

検証の顛末を以下に記します。

# 大勢が想像したであろう共有ストレージの図
これと同じか、似たような絵面 (複数EC2で1ディスクを共有) だと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/e9f680b3-5a49-479f-ff62-0ead3e2f3671.png)
引用: [20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS) 2018/8/9 update](https://www.slideshare.net/AmazonWebServicesJapan/20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update)

この絵面を思い浮かべて想像することは、

* **同じディスクが2台のサーバから見える**
* **片方のサーバから更新したファイルは、もう片方からも見えて更新もできる**


# Multi-Attach EBSを作成して2台でアタッチ
プロビジョンドIOPSでEBSを作って、Multi-Attachにチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/5e58b9df-fcd4-81af-414d-abbe2c9e27d3.png)
2台のEC2 (Windows Server 2019) からアタッチします。
こんなふうに見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/d5b32fcf-044d-bfd4-dcd7-6da2ab6407f3.png)

# 早速Windowsから使おうとしてみる

両サーバからディスクをオンラインにして、ローカルディスクとして使うことを考えます。

記憶域での操作により、両サーバから同時にオンラインにできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/fed94978-8b1a-f313-a032-881665b75d88.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/1563ffe5-ebd1-a31c-7600-1c63c102e4a2.png)

エクスプローラもご覧のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/6156736b-5cb0-0e54-dad9-fd0ae82c14a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/c062a4a3-25b9-59b7-f2e8-8ffa52f0ecae.png)

## ファイル共有できる！ と思いきや
それぞれのWindows Serverの記憶域からはディスクが見えています。
なんかいい感じなので、1台目でテストファイルを置いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/42d1042f-a961-70ce-4121-9ea02e6bc3ec.png)

次に2台目で確認すると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/f286fee2-6387-fb3f-7aa6-2458af3f5328.png)
なんと、**1台目で置いたテキストファイルが見えません。**
これは予想外の展開です。

今度は、逆のことをしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/f59c1b89-b9fe-8986-f457-997ed0e23a05.png)

やはり、1台目では見えません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/253f1165-b486-f1fa-3e19-c0f9e2593fbf.png)

なんと**予想に反して、ファイルの共有ができませんでした。**
ただ、お互いがお互いのファイルを独立して保存できているように見えます。

## もしかして容量が倍になる？
そこで、仮説として、共有ではなく、**1台目と2台目ともに、EBSで割り当てた容量分使えるんじゃないの？** と想像しました。
この仮説が正しいと、今回EBSを20GBで作りましたが、1台目と2台目を合わせて、40GB使えるということになりますが・・・
早速、検証してみました。

`fsutil`コマンドを使い、1台目で容量を埋め尽くしに行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/0c698396-8ed7-2d7f-e0d1-7841983c8375.png)
無事作成できました。

この時点でEBSの20GB中、19GBは埋まっています。

先ほどの検証結果からも分かりますが、2台目では見えていません。
ここで、2台目からも埋め尽くしに行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/60e24169-0ca1-8b88-4a0e-a65908807bc1.png)

なんと作成できました。
この瞬間を切り取ると、**20GBのEBSに、38GBのファイルが保存されていることになります。**

もう一度、マネジメントコンソールでEBSを確認します。
確かに20GBしか割り当てていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/57783460-8ae9-10d1-fd67-afa3d24807f8.png)

この状態で、お互いのファイルは読み取りできました。

## (追記) 片側でディスクをオフラインにして、もう一度オンラインにするとどうなるか
上記までの状態で記事をSNSで共有したところ**「NTFSを両側からオンラインにするとファイルシステムが壊れるんじゃないか」「片側だけオンラインにするべき」**とのメッセージをいただきました。

そこで、上記までの状態で2台目だけディスクをオフラインにしてみますと、正常にオフラインにできました。
その後、もう一度オンラインにすると、**1台目と2台目でディスクの中身が同じとなりました。**
(OSを再起動しても同じ事象が起こりそうです)

再起動やディスクのオフラインを挟むと、その時点でディスクは共有状態となるようですが、その後の書き込み結果はやはり共有されないようです。

## (追記) なぜデータが2倍保存できるように見えたり、突然更新されたりするのか
調査の結果、OSの仕組みから、上記事象の原因が見えてきました。

今回検証したWindows OSでは、ブロックIOのキャッシュを保持しています。
つまり、実際にストレージに対しての書き込みは、OS上の操作とは非同期に行われ、厳密に同時ではありません。
このため、今回のように同じディスクをシンプルに共有した場合、片方で既に更新操作を終えている状況にもかかわらず、もう一方のインスタンスからファイルが存在しないように見えたり、全く利用されていないように見えたり、両方のインスタンスで保存したデータのサイズが実際の物理的な容量と乖離する状況になることがあるようです。
前述の通り、更新が厳密には非同期であり、どちらかのWindows OSが非同期的にディスクに書き込み操作を実行した結果、どちらかのインスタンスでファイルが存在しなくなる状況が起こりかねないと言えます。

現状、このMulti-Attach EBS Volumesをマウントした時のように、**見た目上各サーバのローカルディスクでありながら、物理的にディスクは共有されている**構成には、Windows OSは対応していない (おそらくユースケースとして想定もされていない)と思われます。
対応策として、クラスタソフトウェアなどを導入して、ディスクへの読み書きをちゃんと制御できれば良いのですが、Multi-Attach EBS Volumesに対応しているソフトウェアはなさそうです。

## (追記) IMPORTANT SAFETY TIPSの追記

本件についてAWS様と会話したところ、公式ドキュメントに書かれた以下のTIPSが、まさに上記事象のようなリスクのことであるとご案内いただきました。

> IMPORTANT SAFETY TIP: I mentioned above that your applications do need to provide write ordering to maintain storage consistency, as obviously if multiple instances write data at the same time there is a risk of data being overwritten and becoming inconsistent. Please ensure you fully understand what it takes to set up and run a cluster-aware file system before you attempt to use this feature. The example shown below in this post is for simplicity purposes only, does not use a cluster-aware file system, and is not suitable for production environments!

### Google翻訳
> 重要な安全性のヒント：複数のインスタンスが同時にデータを書き込むと、データが上書きされて一貫性がなくなるリスクがあるため、アプリケーションはストレージの一貫性を維持するために書き込み順序を提供する必要があることを前述しました。この機能を使用する前に、クラスター対応ファイルシステムのセットアップと実行に必要なことを十分に理解してください。この投稿で以下に示す例は、単純化を目的としたものであり、クラスター対応ファイルシステムを使用せず、運用環境には適していません！

ここで、WindowsであればWSFCを構築することが考えられますが、Multi-Attach EBS Volumesは、ディスク単独ではiSCSIには対応しないため、それができません。
(Multi-Attach EBS VolumesをアタッチしたEC2でiSCSIサーバを立てた場合は別ですが、この場合、そもそもMulti-Attach EBS Volumesである必要性がありません。)

# まとめ
2台のWindows Server 2019のEC2にMulti-Attach EBS Volumesをアタッチして両側からオンラインにしても、共有とはならず、最初、互いが容量をフルで使える (実質的に容量が2倍になっている) ように見え、読み書きもできました。
ただ、この状態はあくまで最初に2台をヨーイドンで使い始めて、永続的に起動し続けている間しか成り立たず、再起動等を挟むとこの状態は失われてしまうようです。
**(データロストすることになります)**

つまり、**現在のところ、Multi-Attach EBS Volumesを、公式ドキュメント通りにアタッチして使用しても、Windows Server 2019の標準機能では共有ストレージとして活用できません。**
Active-Active (本検証のようにシンプルに2サーバからマウントした状態) ではデータロスト等の不具合が生じる可能性が大きいことが分かりました。

大勢が想定している共有ストレージとして使うには、アプリケーションやソフトウェアで工夫するか、今後のアップデートを待つしかないようです。

引き続き、現時点でのユースケースを探すべく検証を続けていきますので、分かったことがあれば追記していきます。

# (補足) 「共有ストレージ」とは
この記事を書くときに、タイトルに「共有ストレージ」と書きましたが、その背景としては、

**EBSがMulti-Attachできる→複数EC2から接続できる→同時にマウントして使える?→EFSの代わりになる?**

このように連想する方が少なからずおり、まさに今回実施した検証の内容ができないかと考える方が多いのではと想像しました。
(結果、タイトルの期待を裏切ることになります)

思慮の上、Multi-Attachの文字列を見た人はきっとこう思うんだろうなという想像から、「共有ストレージ」というキーワードを入れています。
賛否はあるかと思いますが、どうか、ご理解いただけたらと思います。

# 参考記事
* [New – Multi-Attach for Provisioned IOPS (io1) Amazon EBS Volumes](https://aws.amazon.com/jp/blogs/aws/new-multi-attach-for-provisioned-iops-io1-amazon-ebs-volumes/)
* [Amazon EBSのマルチアタッチ機能とAzure Shared Disksを比較してみる](https://qiita.com/hayao_k/items/b978cd26622536000a6a)

# 謝辞
本記事を執筆するにあたり、初版執筆時点から、SNS等を通じて技術的なアドバイスをいただいた全ての方に、この場を借りて、改めて感謝申し上げます。