Movable Type を題材にして AWS アーキテクチャ設計を考えてみるシリーズ第4段は、高可用性について考えます。
Movable Type では、可用性を考慮すべきものとして Web サーバ、DB サーバー、App サーバーが考えられます。
サーバーの分離により、データストレージは EFS になっていれば、データ自体の可用性を考慮する必要はなくなっています。そして、そもそも可用性を考えるなら、冗長化が必要になるので必然的に EFS を採用することになると思います。
可用性とは
そもそも可用性とは?
簡単にいうなら使える状態にあることが可用性が高い状態です。
1つしか存在しないものが壊れてしまったら使えなくなってしまいます。家のドアが1箇所しかなくて、そのドアが壊れてしまったら家に入れないです。予備のドアや、外と繋がっている窓があればワンちゃん入れますね。
このようなポイントを単一障害点(Single point of failure:SPOF)といいます。
可用性を上げていくためには、単一障害点をなるべく少なくしていくことが大切です。
構成において単一障害点となるのはどこか?を考えて対策を講じていきます。
マルチ AZ 構成 vs シングル AZ構成
一般的に、VPC 内のリソースの冗長化を行う場合には、複数の AZ を利用したマルチ AZ 構成を採用することが多いです。シングル AZ 内に複数インスタンスを起動することもできますが、AZ レベルの障害が発生する可能性を考えると、AZ が単一障害点になりかねません。
Internet Gateway の可用性
Internet Gateway は、AWS が可用性について考慮と対応を行っているサービスです。したがって、我々は、Internet Gateway 自体についての可用性を考える筆意用はありません。そもそも、1つの VPC に複数の Internet Gateway はくっつけられません。
Web サーバーの可用性
Web サーバーは、1台しか存在しないので単一障害点となります。2台以上の構成にするべきです。
App サーバー(Movable Type)の可用性
App サーバーは、1台しか存在しないので単一障害点となります。2台以上の構成にするべきです。
DB サーバーの可用性
RDS は、マネージドサービスですが、サブネットにリソースを設置するタイプのサービスです。この場合の可用性は、我々が考慮する必要があります。
RDS には、マルチ AZ 配置機能があるので、有効にするだけで自動的にプライマリインスタンスとは別の AZ にスタンバイインスタンスを構築し、プライマリインスタンスとの同期設定も自動的に行われます。
また、プライマリーインスタンスに以上が発生した場合は、プライマリーインスタンスとスタンバイインスタンスの入れ替えを勝手にやってくれます。
EFS の可用性
EFS で構築したファイルシステム自体の可用性を我々は考慮する必要はありませんが、各種サーバーをマルチ AZ 構成で冗長化しているので各 AZ にマウントターゲットを作成する必要があります。
ファイルシステムのマウントには、EFS マウントヘルパーを利用してファイルシステムIDベースで接続すれば AZ の違いは意識せずに利用できます。
サーバーへのリクエストの分散
Web サーバーと App サーバーを2台以上構成したので、それぞれのサーバーがリクエストを受け取れるようにする必要があります。考えられる方法としては、以下の2つが考えられます。
- DNS サーバーにそれぞの EC2 インスタンスのパブリック IP アドレスを複数値回答で登録する
Application Load Balancer による負荷分散
の方法は、パブリック IP アドレスが変わるたびに DNS の書き換えが発生するので厄介です。また、どちらか片方のインスタンスに負荷が集中する可能性が考えられます。
一般的には、2. のApplication Load Balancer を利用してリクエストを分散させる方法が採用されることが多いです。
Application Load Balancer には、リクエスト内容をもとにターゲットグループを振り分ける機能があるので、Web サーバー群へのアクセスと App サーバー郡へのアクセスの両方を1つの ALB で処理できます。また、ALB はフルマネージドサービスなので、我々が可用性について考慮しなくても良い点もいいところです。
マルチ AZ による高可用性の実現
これまでの対策をもとに考えられるアーキテクチャが以下の頭の構成です。
アプリケーションの冗長化に際して考慮するべき点として、セッション維持があります。
Movable Type の場合は、ユーザーのセッション情報はデータベースで管理されているため、複数の App サーバーが存在した場合でもそれぞれの Movable Type は正しくユーザーセッションを確認することができます。
アプリケーションによっては、ローカルストレージにセッション情報を保持する仕組みを採用しているケースがあります。こうした場合は、ALB のスティッキーセッションを有効にする必要があるので注意が必要です。
まとめ
単一障害点となる場所はどこかを考えて必要な冗長化を行うことで高可用性を実現できます。
コストも必然的に上がりますが、システムが停止した場合の被害と比較して考慮するべきです。
(ボクは、被害なんてほとんどないのでそこまでやってませんw)