Ginza.rb 63th で「新規開発で Fastly を使おうと思っている場合、最後に Fastly を入れるのではなく、最初から Fastly 前提で設計したほうがいいですよ」という話をチラッとしたんだけど、終了間際で時間も残っていなくて言葉足らずになってしまったので文章化しました。最初から Fastly 前提で設計すべきと思う理由は以下の3点です。
(1) サイドバーなど、メインのコンテンツとライフサイクルが異なるコンポーネントは非同期にすべきだから
(2) バックエンドのキャッシュ(例えば Rails の MemCacheStore など)はそもそも不要になる可能性があるから
(3) アクセスランキングやアクセスカウンタを作る場合、発想を根本的に変える必要があるため
サイドバーなど、メインのコンテンツとライフサイクルが異なるコンポーネントは非同期にすべきだから
例えばウェブメディアを作っていて、記事の本文の部分も、サイドバーも Fastly でキャッシュしているとします。サイドバーには「人気の記事」といった感じで記事のアクセスランキングが表示されているものとします。記事の本文の部分は、本来その記事自体が更新されない限りキャッシュを purge する必要はないですが、サイドバーのアクセスランキングは1時間に1回更新されるものとします。ページ全体を丸ごとキャッシュしてしまうと、サイドバーのアクセスランキングが更新される度に、記事ページのキャッシュを丸ごと purge することになります。1時間に1回、アクセスランキングが更新される度に、すべての記事ページのキャッシュを purge するとこになるため、origin に無駄なリクエストが飛びます。なのでサイドバーなどメインのコンテンツとライフサイクルが異なるコンポーネントは非同期で取得するなど、何かしらの考慮をしたほうが良いです。
バックエンドのキャッシュ(例えば Rails の MemCacheStore など)はそもそも不要になる可能性があるから
これも要件次第なのですが、Fastly がページキャッシュしていて、そもそも origin にはリクエストがほとんど来ない場合など、例えば Rails の cache_store(MemCacheStoreなど)のようなバックエンドのキャッシュはそもそも不要かもしれないです。上述のウェブメディアの例で言うと、記事の本文の部分をバックエンドでキャッシュした場合、記事の本文を更新して Fastly のキャッシュを purge すると同時にバックエンドのキャッシュも purge することになるので、バックエンドでキャッシュしていてもまったく無意味です。
アクセスランキングやアクセスカウンタを作る場合、発想を根本的に変える必要があるため
例えば Redis の sorted set を使用してアクセスランキングを実装したとします。ブラウザが記事を開こうとして GET /articles/42
といったリクエストを投げても、Fastly が記事をキャッシュしている場合は Fastly がレスポンスを返してしまうので、origin (例えば Rails アプリケーション) にはリクエストが届かず、記事詳細のエンドポイント(Rails であれば例えば ArticlesController#show
) のフィルタなどでアクセス数をインクリメントするような実装ではアクセスカウンタが適切に更新されません。なのでアクセスカウント専用のエンドポイントを用意するなど、Fastly を前提とした設計をする必要があります。
蛇足: その他 Fastly について思うことなど
臭いものに蓋をされてしまう
例えば N+1 クエリーなど、コードベースに問題がある場合でも Fastly がページキャッシュさえすれば高速化できてしまうので、臭いものに蓋をされてしまう。それでも高速には動くので問題ないっちゃ問題ないんだけど、それって本当に問題ないのか??
fastly-rails がメンテされていない件
- https://twitter.com/ttanimichi/status/1029655045283823617
- https://twitter.com/ttanimichi/status/1029659293866328064
- https://twitter.com/ttanimichi/status/1036224049045635079