世界遺産検定サイトへのCloudFront導入のすべて

2019.08.02

はじめに

世界遺産検定とはマイナビグループ会社マイナビ文化事業者が運営している検定です。
本記事では世界遺産検定サイトのCDN導入についてご紹介します。

前置き

世界遺産検定サイトは元々、CMSが入っていない素のPHPとHTMLで構成されたサイトです。

ページの更新や変更がある際は、すべてベンダーに依頼しスポットで開発費を支払っていました。
さらに、スマホ対応していないページも多く、スマホでPCページを見なければならないコンテンツもいくつかありました。

上記2点が大きな理由となり、サイトリニューアルのプロジェクトが始動。
CMSは、社内でも多く使われているWordPressに決定しました。

リニューアルの弊害

2018年11月、およそ半年の期間を経てリニューアルサイトがリリースされました。
WordPressを入れたことによりいろいろな課題が解決されましたが、一方ではメモリの消費量が増加するという弊害も発生しました。

それが最悪の形で現れたのが、リニューアル後の12月11日。
最初の検定の解答発表日となるその日は、最も多くのユーザーが訪れる日でもあります。 ついには同時アクセス数200ほどに達し、メモリを消費しきって、サイトが落ちる事態となってしまいました。

その後、ApacheやWordPressのチューニングを行いましたが、それだけでは根本的な解決に至らず、さらなる安定とサイト速度改善のためCDNを導入することにしました。

CDN導入

CDN導入について、要件は以下のようになりました。

  • フロントはページキャッシュ
  • キャッシュTTLの値は実質無期限とし、コンテンツ更新時に自動で削除
  • 管理画面はキャッシュしない
  • 管理画面に社外からアクセスする場合はBasic認証
  • アクセスログをきちんと収集する

リニューアル後2回目となる検定の解答発表日が2月に迫っており、ベンダーとの調整や環境構築などに割ける時間がなかったため気軽に使えるCDNサービスが候補にあがりました。

AWSならすでに使用できるアカウントがあった上、コンテンツキャッシュやLambda@Edgeについても社内に実績があり必須要件を満たしていたことから、「ひとまずはCloudFrontでいこう」という結論に。

実装のノウハウは検索すれば数多く出てくるのですが、いくつか独自で工夫したポイントをご紹介します。

キャッシュ削除の自動化

世界遺産検定のコンテンツには、固定ページや一般記事のほか、解答速報などの公開日時が厳密に決まっているものがあります。
このため、分単位で公開日時を制御しなければならず、コンテンツ更新時にはキャッシュ削除を行うことが必須でした。この部分を、運用負荷軽減のため自動化しています。
具体的には、C3 Cloudfront Cache ControllerというWordPressプラグインを使用してCloudFrontのキャッシュ削除(Invalidate)のAPIを叩いています。

WordPress管理画面から手動でもキャッシュが削除できるほか、投稿ページ、固定ページを公開する際も自動的にキャッシュ削除のリクエストが走るため、とても使い勝手がよくなりました。
ちなみに、このプラグインはプロキシに対応していなかったため、プラグイン自体も少し改修しています。

管理画面の「プレビュー」の非キャッシュ化

CloudFrontのキャッシュTTLなどのルールは、パスによる指定となります。例えばWordPressの管理画面をキャッシュ対象から外す場合、パスが /wp-admin/* であればTTL=0とするようにルールを設定します。

ところが、WordPressの記事編集でプレビューを行うと、プレビューURLはフロントトップページURL+リクエストパラメータという形になります。
プレビュー画面は記事編集時に開き直すことが多いためキャッシュ対象から外したいわけですが、リクエストパラメータでは直接的にルールを分けられないため、フロント側のルールに基づいてキャッシュされてしまうことになります。

そこで対策として、CloudFrontのエッジコンピューティング用サービスであるLambda@Edgeを活用しました。
具体的には、ビューワーリクエストをトリガーに「リクエストパラメータにpreview=trueが入っていたら、エッジへのリクエストヘッダにシステム日時から導出したハッシュ値を追加」という処理を走らせています。

あとはフロント側のルールで、当該のリクエストヘッダをホワイトリストに加えることで、ヘッダの値でキャッシュの有無を判定してくれるので、プレビューする都度オリジンにコンテンツを取得してくれます。
なお、フロントユーザーがpreview=trueを付けてアクセスした場合は、オリジンのWordPress側でログイン状態をcookieで判断して弾いてくれます。

アクセスログの収集

CloudFrontのログはAWSのS3に出力できますが、一定時間単位でgzipにまとめられて配置されてしまうという課題もありました。
そこで、同じくAWSのAthenaを使って、S3上のログにSQLクエリを投げて検索できるようにしました。
また、出力されたログファイル名そのままではAthenaが解釈できないので、S3にログが置かれるのをトリガーにLambdaを起動してファイルをリネームしています。

結果

CDN導入後は、サイトの安定性が劇的に向上し、その後の2度の解答発表を含めた半年間、一度も障害は発生していません
またサイト速度も0.3秒ほど速くなりました。
下図の通り、キャッシュヒット率は常時80%以上を維持しています。

また、工夫したキャッシュ削除やプレビュー機能も問題なく動いており、サイト運営者はCDN導入前から運用手順を変更することなくコンテンツを編集できています。

料金

AWSのCostExplorerではS3とCloudFront併せて直近では、

  • 4月$6.84
  • 5月$6.53
  • 6月$9.20

でした。
ここまでの成果が出てこの金額ならかなりコスパがいいと思います。

CDN導入の難しさ

今後の追加機能の開発でも、CDNを前提とした調整が必要な案件が出てくると思いますが、システムをあまり知らない人へのCDN導入の説明が難しいと感じました。
サイト運営者(非システム職)にとっては、コンテンツ更新時の1分弱のキャッシュ削除がストレスに感じることもあるようです。
特に、ステージング環境では頻繁にテストを行うため、CDNがあると不便に感じることが多いので利用を止めました。

最後に

WordPressはサイト速度が遅いと言われていますが、CDNなどを導入することでそういったデメリットをカバーすることができます。
今回の記事が皆様のサイト改修の参考となれば幸いです。

余談ですが、今回記事にて紹介した世界遺産検定は四半期に一度程度のペースで実施しています。
よろしければぜひ受験を検討いただければと思います。

世界遺産検定ホームページ:https://www.sekaken.jp/