こんにちは、@Manabu です。
このIT自習室ブログや、私が管理している他のWebアプリはAWSを使用していますが、冗長性を高めるためにEC2を2台使用した構成で運用しています。
そのため、1台のインスタンスが落ちたとしてももう一台が生きているため、サイトが停止することが少なくなると考えていました。
しかし、別サイトのために色々サーバーの中身を操作していると、急にアクセスできなくなり他のブログやアプリについても動かなくなる事象が発生してしまいました。
今回はサイトに起こっている問題について調査した内容と今後の対応について紹介したいと思います。
はじめに
まず、サイトを公開するために使用していたAWSの構成と今回起こった事象について、簡単に説明していきます。
AWSの構成
サイトを公開する環境は、以下の図のような構成になっています。
構成としては、EC2を2台使用することで、サイトの稼働率を上げることを目的とした構成になっています。
EC2へのアクセスが多くなっても、Auto Scalingを使用して、新しいインスタンスを自動で起動しALBで稼働しているEC2にアクセスをルーティングするように構成しています。
そのため、基本的なアクセス数の増加に対しても対応できると想定していました。
発生した事象
そもそもサイトにアクセスできない事態になることを想定していなかったため、なぜアクセスできないのか調査しました。
画面上にはDBへの接続エラーなるものが表示されており、DBに原因があるという推測で色々みてみました。
問題の内容
画面に表示されているエラーの内容から、DBとの接続に関するエラーが発生していることがわかり、データベース周りの内容について確認していきました。
問題の詳細
画像は、CloudWatchの「DatabaseConnections: Sum」という項目のメトリクスで、データベースに対する接続台数の合計を表示したものになっています。
たまに多くなっているタイミングがあります。
DBの最大接続数はいくつで設定されいているのか確認してみると以下のような結果が返ってきました。
mysql> SHOW GLOBAL VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 60 |
+-----------------+-------+
1 row in set (0.00 sec)
mysql>
最大接続数として設定されている値が60であるのに対し、CloudWatchに記録されているログの値は200をこえるタイミングもあることから、DBの最大接続数が原因でエラーが発生しているようでした。
よくある対応
データベースの最大接続数問題に対する一般的な解決策は、システムの安定性とパフォーマンスを向上させるために、主にリソース管理とアプリケーション設計の最適化を目指します。
以下に、そのような対応策の詳細を示します。
コネクションプールの使用
コネクションプールは、アプリケーションとデータベース間の接続を効率的に再利用するための技術です。
アプリケーションがDB接続を必要とするとき、すでに確立された接続を取得し、使用後に再び戻すことで、接続の確立と解放のコストを削減します。
これにより、接続数の急激な増加に対応しやすくなり、レスポンスも短縮されます。
キャッシュの導入
DBの負荷を軽減するために、はキャッシュを導入するのが効果的です。
ページキャッシュやオブジェクトキャッシュを利用して、頻繁にアクセスされるデータやクエリ結果を一時的に保存し、DBへのアクセスを減少させることができます。
今回はCloudFrontを使用してキャッシュを保持していましたが、どうやらうまくいっていないようでした。
リードレプリカの活用
AWSのRDSを使用する場合、リードレプリカを作成して読み取り負荷を分散させることができます。
リードレプリカは、メインのDBからデータを複製することにより、読み取りクエリを処理するために利用され、書き込みクエリの負荷がメインのDBに集中するのを防ぎます。
私の環境では、Wordpressを使ったサイト運営とララベルアプリの個人使用程度だったこともあり、RDSのリードレプリカは使用していませんでした。
これらの方法を適切に組み合わせることで、DBへの接続数を効果的に軽減し、システムの安定性とパフォーマンスを向上させることが可能です。
今後の対応
DBの接続エラーに対するよくある対応について紹介しました。
これとは別に、私が行う対応について紹介します。
S3の静的ウェブホスティング
このサイトや、別で使用しているサイトはすべてWordpressを使用して運用しています。
DBの接続エラーの根本的な解決を図るために、Wordpressをプラグインで静的なコンテンツに変換し、それをAmazon S3でホスティングする方法を検討しました。
以前の記事でも紹介しましたが、このサービスは高い耐久性と可用性を持ち、CloudFrontと合わせることでグローバルに分散されたエッジロケーションを通じてコンテンツの配信が可能になります。
S3の静的ウェブホスティングについては、以下の記事をご覧ください。
AWS構成
S3の静的ウェブホスティングを使用し、以下の図のような構成で更新していくようになります。
開発者は、EC2上のWordpress環境でブログの記事を更新します。
更新した記事はWordpressのプラグインを使用して、静的コンテンツ化しS3へ転送します。
一般のユーザーは、S3にアップされている静的ファイルを閲覧していただくようになります。
S3では、これまで使用していたフォームからのメール送信ができなくなるため、APIゲートウェイを使用してlambdaからSESでメールを送信するようにします。
メリット
対応する構成に関してのメリットは以下です。
・コストの削減
:EC2インスタンスを1台減らすことで、使用料が大きく削減することができます。1台構成ならRDSの削除も検討できるので、さらにコストを減らすことができそうです。
・可用性と耐久性
:S3は高い可用性と耐久性を提供するため、データの損失リスクが提言され、より信頼性の高いサービスが提供可能になります。
・パフォーマンス向上
:S3から直接コンテンツを配信することで、Webサーバーの負荷が軽減され、エンドユーザーに対して高速なレスポンスが可能になります。
デメリット
この構成にすることで、既存の構成に比べてデメリットもあります。
・記事更新の作業工数増加
:これまで、記事を書いて公開することでサイトに表示されていましたが、この構成だと「静的コンテンツ化」と「S3への転送」を行う必要があります。すべて実行可能なプラグインを導入することで簡素化することも可能なようです。
・柔軟性の低下
:静的サイトは、カスタマイズや機能で制限されるため、今まで使えた機能など再検討する必要があります。
まとめ
この記事では、AWS上で運用されているサイト環境におけるDB接続エラーの問題の詳細とよくある対応、そして別の観点からの解決策について紹介しました。
EC2とRDSを使用した元々の動的なサイトの構成から、EC2とS3を組み合わせた静的ウェブホスティングへの移行は、いくつかの懸念点をかかえるものの、メリットはそれを超える大きなものになります。
コストだけでなく、パフォーマンスや耐久性が向上するため、個人でブログを提供するのであれば、一度は検討してみるのが良いかと思います。