ほぼ半年間、すべて順調に見えていました。危なかったのは、その長い平穏でした。
あるWebアプリケーションが共有ストレージにAmazon EFSを使っていました。複数のインスタンスから同じファイルにアクセスでき、デプロイも簡単。設計を疑う理由は、特に見当たりませんでした。
ところが突然、サイトが極端に遅くなり、やがてほとんど動かなくなりました。サーバーの負荷が異常に高くなり、リクエストがタイムアウトし、アプリケーションのプロセスがたまっていきます。
一見すると計算リソースの問題でした。でも違いました。原因はEFSのバーストクレジット残高が尽きたことでした。
CPUの問題に見えた理由
紛らわしかった症状のひとつが、Linuxの高いロードアベレージです。これは必ずしもCPUを使い切ったことを意味しません。ストレージI/Oなどで割り込み不能状態になって待っているプロセスも含まれます。
アプリケーションのワーカーはEFSの処理完了を待っていました。新しいリクエストは到着し続け、待つワーカーが増え、キューが伸びました。
- EFSのスループットが制限される。
- ファイル操作に時間がかかる。
- ワーカーがI/O待ちで埋まる。
- リクエストがたまる。
- システム負荷が上がる。
- ついには、サイトが事実上利用できなくなる。
CPUを増やしても、根本原因は解決しなかったはずです。
なぜ半年も問題が見えなかったのか
このEFSファイルシステムは、 Bursting Throughput モードを使っていました。このモードの持続可能なベースライン性能は、EFS Standardに保存したデータ量に関係します。負荷がベースラインを下回るとクレジットがたまり、上回ると消費されます。
容量の小さなファイルシステムでは、これが誤解を招くことがあります。
- データ量が少ないため、持続可能なベースラインも低い。
- たまったクレジットで、一時的にはずっと高い性能が出る。
- 長期的な負荷はベースラインを超えているのに、アプリは普通に動く。
- クレジットが残っている間は、不均衡が隠れる。
- 残高がゼロになると、性能が大きく落ちる。
このケースでは、蓄積したクレジットが約半年持ちました。スループットの観点では最初から不足していた設計を、残高が隠していたのです。ゆっくり進む容量不足、半年かけて時を刻む時限爆弾でした。
一時的なバースト性能を、持続可能な性能と取り違えてはいけません。
適切なEFSスループットモードを選ぶ
Bursting Throughput
Bursting Throughputは、データ量に応じて性能要求も増え、繁忙期の後に十分な閑散期が来る負荷に向いています。ただし監視が欠かせません。残高が下がり続けるなら、そのモードでは負荷を維持できません。
Elastic Throughput
Elastic Throughputは、予測しにくく変動の大きい負荷に一般的に向いています。需要に合わせて性能が自動的に伸び、有限のバーストクレジットに依存しません。運用の安心感は増しますが、常に高いI/Oがある場合は従量課金を評価する必要があります。
Provisioned Throughput
Provisioned Throughputは、必要性能がわかっていて、データ量から得られる性能を上回る場合に役立ちます。容量と独立して性能を確保できますが、需要が変わったら設定を見直す責任があります。
また、EFSの スループットモード と パフォーマンスモードは別物です。前者は性能容量をどう供給するか、後者は遅延や並列性などの特性に関わります。
本来、監視しておくべきだったもの
Bursting Throughputで最も重要なCloudWatchメトリクスは、 BurstCreditBalanceです。基本の監視には、次も含めます。
BurstCreditBalanceで継続的なクレジット減少を把握PercentIOLimitでI/O上限への接近を把握PermittedThroughputで現在使えるスループットを把握MeteredIOBytesおよびTotalIOBytesでI/O消費量を把握- アプリの遅延、リクエスト時間、タイムアウト、エラー率
- I/O待ちのプロセスを、ロードと実際のCPU使用率と合わせて確認
CPU、メモリ、HTTPステータスだけでは不十分です。共有ストレージはアプリの重要な依存先であり、単なるインフラ部品ではなく、サービスの一部として監視する必要があります。
残高がゼロになるより十分早くアラームを上げるべきです。さらに重要なのが傾向です。何週間も一貫して下がっていれば、絶対量がまだ十分に見えても、構造的な性能不足が表れています。
今なら、こうする
- 設計段階で持続可能なスループットを見積もる。
- 実際のアクセスパターンからモードを選ぶ。
- クレジットは通常の容量ではなく、一時的な余力と考える。
- 残高とI/O上限のCloudWatchアラームを作る。
- クレジットの消費速度を監視する。
- 負荷試験にEFSの性能と遅延を含める。
- Linuxのロード、CPU使用率、I/O待ちを突き合わせる。
- 頻繁に読むファイルに、本当に共有ネットワークストレージが必要か見直す。
- ストレージのスロットリングや高遅延時のアプリの挙動を試す。
- スループットモードを変更する運用手順を残す。
この障害から学んだこと
EFSは優れた共有ストレージになり得ますが、挙動は選んだモードと負荷の特性に強く左右されます。
危険だったのは、単に性能が悪化したことではありません。悪化するまで半年も快調だったことです。クレジットが問題の表面化を遅らせ、持続できない設計への安心感を生んでいました。
最善の対策は、残高を増やすことではありません。適切なモードを選び、持続可能な性能を理解し、不均衡が大きくなる兆候を利用者より先に見つけることです。


クラウド / システム