Upgrade to Pro — share decks privately, control downloads, hide ads and more …

月間7500万PVのサービスのCDNをFastlyに移行してみた

 月間7500万PVのサービスのCDNをFastlyに移行してみた

Fastly社主催のYamagoya 2023で登壇したときの発表資料です。
https://v2.nex-pro.com/campaign/60418/apply

shinyasakurai

November 10, 2023
Tweet

More Decks by shinyasakurai

Other Decks in Programming

Transcript

  1. 月間7500万PVのサービスの
    CDNをFastlyに移行してみた
    @Yamagoya 2023
    PR TIMES 開発本部 インフラチームテックリード
    櫻井 慎也

    View full-size slide

  2. 自己紹介
    櫻井 慎也
    PR TIMES 新卒6年目
    開発本部 インフラチーム テックリード
    https://developers.prtimes.jp/2023/04/18/prtimes-cdn-fastly/
    https://developers.prtimes.jp/2022/12/01/prtimes-aws-migration/
    https://developers.prtimes.jp/2023/09/07/newrelic_extension/

    View full-size slide

  3. プレスリリース配信サービス
    PR TIMESについて

    View full-size slide

  4. 2022年2月にFastly ImageOptimizerを導入して
    一部のプレスリリース画像の画質を改善しました
    https://developers.prtimes.jp/2022/02/24/press_release_image_optimization/
    当時新卒一年目の
    メンバーが
    やり遂げてくれま
    した
    🙌

    View full-size slide

  5. 圧縮率の高い画像形式である
    WebPを使うことで
    画像の高画質化と軽量化を
    両立!

    View full-size slide

  6. 2023年3月にはPR TIMES STORYでAVIFやWebP
    画像を配信するのにImageOptimizerを活用しました
    https://developers.prtimes.jp/2023/03/02/use_avif_and_webp_for_story_thumbnail_images/

    View full-size slide

  7. スマートフォンページのLighthouseの結果

    View full-size slide

  8. PCページのLighthouseの結果

    View full-size slide

  9. そして2023年4月にPR TIMESのほぼ全ての
    ページをCloudFrontからFastlyへ移行しました
    https://developers.prtimes.jp/2023/04/18/prtimes-cdn-fastly/
    今回は
    こちらについて
    話します!

    View full-size slide

  10. 今回の発表では
    ● なぜ移行する必要があったのか
    ● 移行するために対応したこと
    ● 具体的な移行手順
    ● 移行して分かったFastlyの良いところ
    今回の発表では
    今回の発表では
    を紹介します

    View full-size slide

  11. ● なぜ移行する必要があったのか
    ● 移行するために対応したこと
    ● 具体的な移行手順
    ● 移行して分かったFastlyの良いところ

    View full-size slide

  12. なぜ移行する必要があったのか
    Smarty テンプレート + jQueryで構築されたレガシーなフロントエンド
    をReactでリプレイスしていくプロジェクトが進行中
    → 検索エンジンになるべく早くインデックスさせるために
    サーバーサイドレンダリングとその結果をキャッシュする仕組みが必要
    → VCLを使った柔軟なキャッシュ戦略を取ることができる
    Fastlyへの移行が必要不可欠

    View full-size slide

  13. ● なぜ移行する必要があったのか
    ● 移行するために対応したこと
    ● 具体的な移行手順
    ● 移行して分かったFastlyの良いところ

    View full-size slide

  14. カスタムVCLを導入
    Fastlyの大きな特徴であるVCLを使った柔軟な設定の強みを
    活かすためにカスタムVCLを導入しました。
    まず初めに Using VCL > Custom VCL にある
    VCLのボイラープレートをそのままコピーして動作確認
    しました。
    その後、必要な要件に応じて様々な設定を追加しました。

    View full-size slide

  15. VCLのライフサイクル

    View full-size slide

  16. カスタムVCLのマクロについて
    カスタムVCL に含まれている #FASTLY recv のような
    コメントはマクロとして設定されており、
    この部分にカスタムVCL外の設定が展開されます。
    → そのため、設定を追加する場合はこのコメントより
    前に書くとマクロに上書きされてしまう場合があります。

    View full-size slide

  17. カスタムVCLのマクロについて
    ここにカスタムVCL外
    の設定が展開される

    View full-size slide

  18. #FASTLY hit から
    展開された部分

    View full-size slide

  19. マクロ展開後の
    VCL全体
    バージョンごとの
    VCLの変更差分
    設定を反映した後でVCLの差分やVCL全体を確認する

    View full-size slide

  20. パスベースのルーティング設定
    PR TIMESではprtimes.jpドメインのサブディレクトリに
    別サーバーで動く複数のサービスがあります。
    PR TIMES
    (/)
    PR TIMES Web クリッピング (/webclipping)
    PR TIMES STORY (/story)
    PR TIMES MAGAZINE (/magazine)
    など

    View full-size slide

  21. パスベースのルーティング設定
    マクロに上書き
    されないように
    #FASTLY recv
    より下に記述

    View full-size slide

  22. Cache-Controlヘッダーの設定
    Fastlyを含め一般的なCDNではCache-Controlヘッダーなどの値を元に
    CDNでキャッシュするかどうかを判定します。
    ここで注意する必要があるのがデフォルトのVCL設定だと
    ● Cache-Controlヘッダーがない場合はキャッシュされる
    ● Cache-Control: no-cacheはキャッシュされる
    ということです。
    さらに、カスタムVCLを使わないデフォルトの状態だと
    ● Cache-Control: no-storeもキャッシュされる
    という落とし穴もあります。

    View full-size slide

  23. Cache-Controlヘッダーがない場合
    HTTP は可能な限りキャッシュするように設計されているの
    で、Cache-Control が指定されていなくても、ある条件が
    満たされればレスポンスは格納されて再利用されます。
    これはヒューリスティックキャッシュと呼ばれます。
    HTTP - HTTP | MDN
    キャッシュ より引用

    View full-size slide

  24. Cache-Controlヘッダーがない場合
    ヒューリスティックキャッシュの有効期限はLast-Modified
    ヘッダなどの値を元に算出することが多いですが、
    Fastlyでは3600秒をデフォルトの有効期限に設定しています。
    (VCLから変更することも可能)

    View full-size slide

  25. Cache-Control: no-cacheはキャッシュされる
    no-cache はキャッシュにレスポンスを保存することを許可
    しますが、再利用する前に再検証することを要求します。
    もし、「キャッシュさせない」の意味が実際には
    「保存させない」であるなら、no-store が使用すべき
    ディレクティブです。
    Cache-Control - HTTP | MDN より引用

    View full-size slide

  26. Cache-Control: no-cacheはキャッシュされる
    再利用する前に再検証してくれるなら大丈夫じゃないの?
    と思うかもしれませんが、残念ながらFastlyでは
    no-cacheのときキャッシュの再検証をしてくれません!
    (再検証の仕組みを自力でカスタムVCLに実装すれば
    実現は可能)

    View full-size slide

  27. Cache-Control: no-storeもキャッシュされる場合がある
    カスタムVCLのボイラープレートを使っていない場合、
    オリジンサーバーが Cache-Control: no-store を返しても
    キャッシュされてしまうことがあります。
    if文の条件に
    no-storeが入っていない

    View full-size slide

  28. Cache-Controlヘッダーの値によるCDNのキャッシュ可否
    private
    max-age=0
    s-maxage=0
    no-store no-cache それ以外
    Fastly
    (カスタムVCLあり)
    しない しない する
    (再検証なし)
    する
    Fastly
    (カスタムVCLなし)
    しない する する
    (再検証なし)
    する
    CloudFront しない しない する
    (再検証あり)
    する

    View full-size slide

  29. Cache-Controlヘッダーの挙動について
    これが想定通りの挙動なら大丈夫ですが、そうでない場合は
    個人情報漏えいにもつながりかねない重要な設定です。
    特にキャッシュされるはずのものがキャッシュされないこと
    よりキャッシュされないはずのものがキャッシュされること
    の方が重大なインシデントに繋がりやすいです。

    View full-size slide

  30. Cache-Controlヘッダーの設定を変更
    今回はアプリケーション側の修正箇所の多さと
    対応漏れによるキャッシュ事故のリスクを考慮して
    ● Cache-Control ヘッダーがない場合はキャッシュされない
    ● Cache-Control: no-cache はキャッシュされない
    となるようにカスタムVCLを変更しました。

    View full-size slide

  31. Cache-Controlヘッダーの設定を変更
    Cache-Control: no-cache
    の場合もキャッシュしない
    変更後のVCL
    変更前のVCL
    Cache-Control ヘッダーがない
    場合はキャッシュしない

    View full-size slide

  32. 配信可能なオブジェクトのサイズ上限
    (2020年6月17日以降に作成されたアカウントの場合)
    Fastlyで配信できるオブジェクトのサイズが最大20MBになっており、
    これを超える場合は 503 Response object too large エラーが発生します。
    これを回避するためには
    ● セグメントキャッシュの利用
    ● オブジェクトサイズの上限引き上げ依頼
    のいずれかを行う必要があります。

    View full-size slide

  33. セグメントキャッシュの利用
    セグメントキャッシュ = オブジェクトを分割してキャッシュできる機能
    これを使うと配信可能なオブジェクトのサイズが無制限になります。
    ただし
    ● オリジンサーバーがRangeリクエストに対応している
    ● 動的に生成されたコンテンツは不可
    などの条件があるため注意が必要です。

    View full-size slide

  34. オブジェクトサイズの上限引き上げ依頼
    PR TIMESではプレスリリースのPDFダウンロード機能などで
    オブジェクトサイズが20MBを超える場合がありました。
    しかしサーバーがRangeリクエストに対応しておらずセグメント
    キャッシュの利用は難しかったため、サポートに問い合わせて
    オブジェクトサイズの上限を50MBまで引き上げていただきまし
    た。

    View full-size slide

  35. Cookie内のセッションIDのハッシュ化
    Fastlyから出力するアクセスログのフォーマットは自由に
    変更することができ、Cookieを追加することもできます。
    しかしCookieにはユーザーのセッションIDが含まれている
    場合があるため、万が一アクセスログが漏洩してしまった
    場合に大きなセキュリティリスクになります。

    View full-size slide

  36. Cookie内のセッションIDのハッシュ化
    アクセスログに書き込む前にCookie内のセッションIDを
    ハッシュ化することで、万が一漏洩してしまった場合の
    リスクを抑えながらユーザーを識別できるようにしました。

    View full-size slide

  37. Cookie内のセッションIDのハッシュ化
    ログ出力の” ”
    前 なので
    #FASTLY log
    よりも前に書く

    View full-size slide

  38. メンテナンス画面の設定
    データベースのバージョンアップ時など、サービス全体で
    メンテナンス画面を表示させるという要件もVCLを使って
    簡単に実現できます。

    View full-size slide

  39. メンテナンス画面の設定 (ディクショナリ)
    まずはメンテナンス状態の切り替え用のディクショナリを
    作成します。
    ディクショナリはバージョンを更新することなく変更する
    ことができます。

    View full-size slide

  40. メンテナンス画面の設定 (HTMLファイル)
    Terraformを使っている場合、以下のようにしてメンテナンス用の
    HTMLファイルをカスタムVCL内に渡すことができます。

    View full-size slide

  41. service_configディクショナリの
    maintenance が true なら
    600エラーを発生させる
    (他のエラーと被らないように
    存在しないステータスコード
    を使うのがおすすめ)
    メンテナンス画面の設定 (VCL)

    View full-size slide

  42. 600エラーが発生しているなら
    ステータスコードを503に設定して
    メンテナンスページを表示する
    直接HTMLを書いてもOK
    メンテナンス画面の設定 (VCL)

    View full-size slide

  43. メンテナンス画面の設定
    600エラーを発生させるときのif文に条件を加えることで
    メンテナンス画面を表示させる条件を柔軟に変更できます。
    ● 特定のIPアドレスのみ通過させる
    ● 特定のページのみメンテナンス画面を表示させる
    など

    View full-size slide

  44. ● なぜ移行する必要があったのか
    ● 移行するために対応したこと
    ● 具体的な移行手順
    ● 移行して分かったFastlyの良いところ

    View full-size slide

  45. CDN Serviceの作成
    まず初めにCDN Serviceを作成しました。
    このとき先ほど紹介したカスタムVCLのボイラープレートを
    有効化しておくと後で設定を変更するときに便利なので
    オススメです。

    View full-size slide

  46. TLS証明書の取得
    次に独自ドメインでHTTPSを使うためにTLS証明書を取得
    しました。
    外部で取得した証明書をインポートすることも可能ですが、
    更新作業が不要なFastly TLSを使って取得するのがオススメ
    です。

    View full-size slide

  47. TLS証明書の取得
    Fastly TLSでは認証局を以下から選択できます。
    ● Let’s Encrypt : 無料の認証局
    ● Certainly : Fastlyの提供する認証局
    ● GlobalSign : 有料の認証局
    Let’s EncryptとCertainlyは追加料金なしで利用できます。
    (無料アカウントなら2個、有料アカウントなら5個までで
    それ以降は1ドメインごとに$20/月)

    View full-size slide

  48. /etc/hosts を使った動作確認
    次にローカルマシンの /etc/hosts に以下のように追記して
    動作確認を行いながらVCLの設定を変更しました。
    151.101.1.55 prtimes.jp
    Fastly TLSで証明書を取得後に得られる
    Anycast IPアドレス

    View full-size slide

  49. 本番環境でのFastlyへの移行
    次に実際に本番環境のCDNをFastlyに切り替えていきますが、
    Fastly上にキャッシュがまだないので全て一度に切り替えると
    オリジンサーバーに負荷がかかる可能性があります。
    → Route53の加重ルーティング機能を使って
    段階的に移行を行いました。

    View full-size slide

  50. 本番環境でのFastlyへの移行

    View full-size slide

  51. 本番環境でのFastlyへの移行

    View full-size slide

  52. 本番環境でのFastlyへの移行

    View full-size slide

  53. 本番環境でのFastlyへの移行

    View full-size slide

  54. 本番環境でのFastlyへの移行

    View full-size slide

  55. ● なぜ移行する必要があったのか
    ● 移行するために対応したこと
    ● 具体的な移行手順
    ● 移行して分かったFastlyの良いところ

    View full-size slide

  56. VCLによる柔軟な設定ができる
    先ほど紹介したパスベースのルーティング設定や
    セッションIDのハッシュ化、メンテナンス画面の設定など
    カスタムVCLを使ってCDNの動作を柔軟に変更することが
    できます。

    View full-size slide

  57. キャッシュパージが高速かつ柔軟
    キャッシュをパージする方法は
    ● 単一URLのパージ
    ● 特定のサロゲートキーの一括パージ
    ● 全てのURLの一括パージ
    を選択でき、どれも非常に高速に実行できます。(1秒以下)
    また、サロゲートキーを使うことで特定のユーザーの画像
    のみキャッシュパージするなどの要件が簡単に実現できます。

    View full-size slide

  58. サポートが手厚い
    今回の移行に伴いエンタープライズサポートを契約し、
    移行のサポートをしていただきました。
    VCLについてだけでなくTerraformのコードまで踏み込んで
    サポートいただきました。
    また、運用後にエラーの発生している箇所について
    能動的に改善提案をいただきとても助かりました。

    View full-size slide

  59. 最後に
    今回あまり紹介できなかったImageOptimizerの活用事例なども
    書いているのでぜひ開発者ブログも読んでみてください!
    https://developers.prtimes.jp/tag/fastly/
    prtimes 開発者ブログ fastly

    View full-size slide