動的コンテンツを Fastly CDN でオフロードする方法

# はじめに
Fastly は CDN などのネットワークサービスや Web Application Firewall, DDoS、Bot対策などのセキュリティ対策、Edge Compute サービスを提供していますが、CDN の機能としてはリアルタイム性が高いことと設定の柔軟性の高さが大きな特徴となっています。

ここでいうリアルタイム性とは以下の３種類です
1. インスタント Purge = CDN 上にキャッシュしたコンテンツを削除
2. ログ配信 = リクエストを処理したログを指定のエンドポイントに送信
3. 設定変更 = UI や API で行った配信設定の変更が反映されるまでの時間

この記事では インスタント Purge を活用し、リアルタイム性が求められるコンテンツをオフロードする方法について説明します。

# Purge とは
Purge とは CDN にキャッシュされたオブジェクトを削除することいいます。例えばコンテンツの更新が発生した場合やキャッシュしてはいけないコンテンツをキャッシュしてしまった場合などに利用します。

Fastly ではこの Purge を UI や API からリクエストを送ってから約150ms で完了することができます。150ms ですので Purge リクエストを送った瞬間にはキャッシュが削除されているイメージです。

Fastly が世に出てきてから他の CDN ベンダーもパージの速度の改善に力をいれていますが、ここまでの速度でキャッシュを削除できるのは依然として Fastly 独自の強みとなっています。

どのような仕組みで高速な Purge が実現されているかは以下のブログなどに記載されているので興味がある人は読んで頂ければと思います。
https://www.fastly.com/blog/building-fast-and-reliable-purging-system/

# ２種類の動的コンテンツ
動的コンテンツ、と聞くとどのようなコンテンツをイメージするでしょうか？
一般的に動的コンテンツというと、以下の２種類のコンテンツをイメージされる方が多いと思います。

- **パーソナライズされたコンテンツ**
ようこそ XXX さん、といった表示やログインユーザーのアクセス履歴に合わせたおすすめの商品などユーザーごとに動的に生成されるコンテンツです。
　
- **リアルタイム性が求められるコンテンツ**
スポーツのリアルタイム速報や、選挙の速報、商品やホテルの空き部屋などの在庫情報など最新の状況を届ける必要があるコンテンツです。何かのイベント（得点がはいったり在庫情報の変更）でコンテンツが更新されるので `イベントドリブンコンテンツ` とも呼びます。

このふたつのコンテンツは動的に生成されることが多く一括りに語られることが多いのですが、大きな違いとしては後者はすべてのユーザーが同じコンテンツを共有することが出来るという特徴があります。

すべてのユーザーが同じコンテンツをみるのであれば CDN でキャッシュをしてオフロードしたいのですが、従来の CDN ではリアルタイム性が求められる点が課題になります。

一般的な CDN ではキャッシュを削除するのに数分以上の時間を要するため、キャッシュをしてしまうとリアルタイム性が損なわれてしまいます。そのため、こういったリアルタイム性が求められるコンテンツに対してはキャッシュをしない、もしくは1-2秒程度といったごく短いTTLを設定するといった対処が限界でした。

# Fastly を利用したリアルタイムコンテンツのキャッシュ
Fastly のインスタントパージ機能を活用することで、リアルタイム性を保持しながらキャッシュを最大限有効に利用することが可能です。

Fastly ではキャッシュをほぼ瞬間的に削除することが出来るので、リアルタイム性が必要なイベントドリブンコンテンツでも1日などの長い TTL を設定し、更新が発生したタイミングで Purge リクエストを送信するという運用が可能です。

こうすることでコンテンツのリアルタイム性を保持しながら、更新が発生していない限りキャッシュからレスポンスが返却出来るのでコンテンツの配信が高速に行われることに加え、オリジン側のインフラへのリクエストも最小限に抑えることができます。

ただし、コンテンツの更新のたびに手動で Purge リクエストを送信するのは現実的でないので、CMS などのコンテンツ管理システムがコンテンツを更新を行うと自動的に Purge リクエストを送信する仕組みを構築することが望ましいです。

動作イメージとしては以下のような構成になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128569/0eee4234-8e3b-a3cc-ed2b-4ce89cae5f28.png)


# Surrogate-key でコンテンツをまとめて更新
ここまでの説明では Purge リクエストを送って特定のひとつのオブジェクト（URL）を更新するイメージでしたが、Fastly には Surrogate-Key という複数のオブジェクトにタグを設定し、同じタグを持つオブジェクトをまとめて削除する機能があります。

この機能を利用することで特定のページに含まれるすべてのオブジェクトや、特定の商品に関連するすべての画像などコンテンツを自由にグルーピングし、1回のリクエストでまとめて削除することが可能になります。

サロゲートキーの詳細は以下のページをご参照下さい。
https://docs.fastly.com/ja/guides/working-with-surrogate-keys


# パーソナライズコンテンツのキャッシュ
もうひとつの動的コンテンツであるパーソナライズコンテンツは通常キャッシュしてもあまり負荷効果がありません。ただしページを生成するコストが高い、同じユーザーが何度もアクセスしてくる可能性があるサービスの場合はキャッシュ効果があるかもしれません。

たとえば自分の購入した飛行機や電車のチケット情報のページなどは、遅延などが発生していないかを確認するためひとりのユーザーが何度もページにアクセスしてくる可能性が考えられます。

Fastly では同じ URL でも Vary ヘッダを利用してユーザーごとにキャッシュコンテンツを持ち分けることが可能なので、サービスの性格次第ではイベントドリブンと同様にインスタント Purge 機能を利用することでパーソナライズコンテンツのキャッシュを検討してみても良いかもしれません。

ただしパーソナライズコンテンツをキャッシュする際はリクエストの認証を追加するなど個人情報が第三者に配信されてしまうことがないように細心の注意を払う必要があります。

# まとめ
この記事では Fastly のインスタント Purge 機能を利用し、動的に生成されるページをキャッシュする方法について説明しました。動的に生成されるページでもページの性格によってはキャッシュを有効活用することが可能です。

Fastly CDN の活用方法としてはベーシックなユースケースなのですが、意外と知らなかったと言われることが多いので記事にまとめてみました。インスタント Purge 機能は無料ので作成できる開発者アカウントでも利用可能なので是非実際にお試しいただけると嬉しいです。