HTBの新作配信でCloudflareのキャッシュの挙動を壮絶に調査した件
この記事は、「HTB Development Team with Friends Advent Calendar 2023」の12月7日分の記事です。
副題は「副題:三浦さんとCloudflareとCache Eviction(と大栗さん)」です。今年三浦さんとの付き合いといえば、Cloudflare Meet-upを1月に立ち上げてもらったことと、お仕事でも付き合いがあったことです。
肝煎りコンテンツの新作動画配信でCloudflareを採用してもらいました。
完全なる従量課金ではなく、1年間毎月新作公開をしても予算を超過しないという思い切った提案となりました。クラウドの従量課金は素晴らしい考え方であることは事実ですが、企業全体がまだデジタルに造詣が浅い場合、様々な試行錯誤とコストが連動するため、確定効果が見込めないものは承認がされないケースなどが考えられます。せっかくならデジタル領域において三浦さんに1年間思いっきりいろいろやってもらえるようにしたいと思い、社内でもいろいろ調整したのを覚えています。そんなこんなで第一回目の配信を迎えました!
成功した第一回目の配信
新作配信は5週間にわたって毎週定期的に1話ずつ配信が開始される構成でした。Cloudflareの構成としてはAmazon S3互換ストレージのR2をオリジンとして使い、CDNで配信するというスタンダード構成です。
R2はストレージ料金がS3の約半額、通信料金無料というコスト削減を大きく実現するストレージです。そこにオンデマンド用(DRMがかかった)コンテンツを配置し、Cloudflare CDNで配信する構成です。
実はPartnerであるClassmethod大栗さんやCloudflareのSEなどの手を借りずに、HTBさんが単独でで構築しています。すごい技術力と調査力・・・・
そして迎えた第一回目の配信は無事終了し、同様に翌週の第二回目も無事終了しました。
そして起こった問題
3週目の配信を迎えた直前の夜、三浦さんからメッセがきました。
CDNキャッシュがすぐ消えるためオリジンに頻繁に取りに行く。しかもその速度が遅いと思う。
Classmethod大栗さんと私でFacebookメッセンジャーなどでやり取りを行い、自分で動作検証してみると、確かにキャッシュが早めに消えるケースがあります。そこから社内のサポートとも連携し大調査が開始されました。
Cacheが消える件は後で触れるとしてまずはR2から
Cloudflareにはリージョンという概念が原則ありません。R2はGlobalのCloudflareのエッジどこかに作られます。なるべくバケットを操作するクライアントの近くに作ろうとする、という仕様です。これは仕様として良いとして、課題はどこの国にバケットが作られていることがわからないことです。これはCloudflare側の管理画面の改善ポイントだと思います。東京にできることもあれば、APJCのどこかにできることもあれば、別の国にできることもあります。R2を使うときはまずエンドポイントのレイテンシを見る、ということを三浦さんに伝えきれていなかった私のミスです。申し訳ありません。
調査の結果、結論としてイタリアにできていました。しかも我々がテストしていた時は日本の夜中、それはイタリアのGW中の昼間、ということでまずR2が遅い原因が判明しました。三浦さんにそれを説明し再度Location Hint
というパラメータを付与してバケットを再作成してもらい、データを移行しました。
Location Hint
というのは、指定された地域(国ではなく地域)にバケットを作成することを可能な限り優先する、というオプションです。AWS育ちの私には最初は衝撃の仕様でしたが、Cloudflareのコンセプトに基づいてそうなっています。したがってLocation Hint
を使ったとしてもエンドポイントのレイテンシの確認は必須です。
これによりR2のパフォーマンス問題は解決しました。
さて、本題のCacheが消える問題
確かにブラウザからテストを行うとキャッシュがTTL設定を無視して消えるように見えます。Cloudflare内部サポートとも連携をしながら調査を進めると、秒間数件のアクセスであればキャッシュは比較的早く破棄され、商用レベルの安定したアクセスがあればキャッシュはTTLの期間保持される、というCache Evictionの動作に行き当たりました。
つまり数人がブラウザでテストしている分にはあまり意味がない、ということです。経験上CDNに携わるのはCloudflareで実は4社目ですが、この積極的なCache EvictionはCloudflareのコスト効率に貢献している動作ですが、初めて体験する仕様だったので三浦さんへの伝達が遅れてしまいました。私の反省ポイントその2です。
では商用レベルのテストをどうするかなどを色々議論しました。TVerの内部ツールである、千手観音
の投入なども案に上がりましたが、会社をまたいだ協力依頼などは時間がかかることも想定され一旦見送ることとしました。
Cloudflare側でCacheを多段にするTiered Cache
オプションをオンにすることでその問題は解決しました。
Tiered Cache
とはCacheを多段にすることによって、Cache全体がもつストレージ能力を控除させる仕組みです。これによりCacheが頻繁にEviction(削除)されてしまう現象を減らすことが出来ます。
本番に戻すかどうか
ある程度の調査結果が出尽くし必要な対応も終わった後、一番難しい問題は本番に戻すかどうか、です。千手観音
の投入を見送ったこともあり、商用レベルでの負荷テストは十分には行えていない状態です。とにかく時間が足りませんでした。Cloudflare側のサポートも問題ないと断言していたのもあるでしょうが、ここで三浦さんの男気です。通常であれば、もっと負荷テストを行い問題は無いというデータを積み上げるという時間のかかる作業をしなければ難しかったところ、必要関係者のアイデアが出尽くしていることもあり、その人たちの判断に託すことにしたのでしょう。この辺りの男気が、三浦さんの周りに多くの人が集まる最大の理由ですね。Cloudflareも助けられました。
私も後方支援としてその調査結果をまとめたブログを執筆し関係者に状況(や仕様)が伝わるようにしていました。
そして迎えた、本番
はい、問題なく配信できました。つまり初回から商用レベルのアクセスであれば問題は発生していませんでした。これは正しく仕様を把握し、最初からまとめて伝えられていなかった私の反省点です。
とはいえ、おつかれさまでしたー!
その他気づいた課題
調査の過程にて、あきらかに動画配信開始時間とは別の時間に大量のアクセスがあることがわかりました。これはメディア系固有の現象ですが、おそらくBotがそのコンテンツを不正にダウンロードしようとしていると予想されます。CloudflareにはSuper Fighting Bot Mode
というのがあり、商用のCDN契約では無償で利用が可能です。これをオンにすることで不正なアクセスを大幅に軽減させることが出来ました。ボタン一つで設定が可能です。また類似のモードとしてUnder Attack Mode
というのもあります。これも同様にBotからのアクセスを防ぎます。前者がBotを主眼に置いたもの、後者はBotも含めたDDoSを主眼に置いたもの、という違いです。
まとめ
おつかれさまでしたー!今後ともよろしくお願いします!
Discussion