キャッシュ設計(1) - イベントドリブン

# イベントドリブンコンテンツ

従来、Webサイトのコンテンツは**静的なコンテンツ**と、**動的なコンテンツ**の２種類のコンテンツに分けられていました。CSSなどは静的で、Webアプリケーションが出力するコンテンツは動的と言った具合です。実際に多くのWebアプリケーションが以下のデフォルトのヘッダーを出力します。

```
Cache-Control: max-age=0, private, must-revalidate
```

例えばこの[野菜たっぷりドライカレー](https://cookpad.com/recipe/280526)のレシピのコンテンツのヘッダーも上記の通りです。**有効期間0秒、共有キャッシュにおいてはならない、再確認が必要** というヘッダーが返却されます。本当でしょうか？

この記事では従来キャッシュが出来ないと思われいたコンテンツに対処するための分散キャッシュシステムの設計と実装を検討します。どのようなキャッシュシステムが理想的でしょうか。最初にFastlyの[記事](https://www.fastly.com/blog/rise-event-driven-content-or-how-cache-more-edg
)を紹介します。

## The Rise of Event-Driven Content

>  CDNユーザーは動的コンテンツは決してキャッシュできないと教えられてきたにもかかわらず、多くの場合、それはキャッシュ可能です。... 「静的」と「動的」では、世の中にあるさまざまなタイプのコンテンツをすべて表現するには不十分であることが明らかになりました。

従来の静的、動的では捉えれないコンテンツの存在の話から記事が始まります。

### 静的コンテンツ

> 静的コンテンツとは、一般によく知られているように、あまり頻繁に変化しない（変化するとしても予測可能な）コンテンツのことです。画像、CSS、JavaScriptはこのカテゴリに属し、サイトやアプリケーションで使用される他の多くのめったに変更されないコンテンツも同様です。静的コンテンツは、Cache-Controlヘッダや、さまざまな種類のオブジェクトにTTL（time to live）を適用する詳細な設定によってキャッシュされます。静的コンテンツでは、キャッシュする期間を前もって知ることができます。

> CDNは静的コンテンツを予想通りに処理します。

静的ファイルはRESTのキャッシュに完璧にフィットして、サーバーサイドだけなくネットワーク資源も節約します。

### 動的コンテンツ

> 動的なオブジェクトは、毎回ユニークで、同じものは二度とありません。AJAXの呼び出しは、しばしば動的です。ユーザーのログインやクレジットカード決済など、高度にパーソナライズされたコンテンツもこのカテゴリーに属します。
> CDN（あるいはその他のキャッシュ）は、基本的には動的コンテンツをキャッシュすることはできません。


### イベントドリブン型コンテンツ

> イベントドリブン・コンテンツは、動的コンテンツのように見えて、キャッシュされることはないと言われてきました。しかし実は、従来のCDNにはこの種のコンテンツをキャッシュするための適切な仕組みや機能がなかったのです。

> 動的コンテンツが本当にキャッシュできないのに対して、イベントドリブン型コンテンツは、実際にはキャッシュできるのですが、予測不可能です。イベントドリブン・コンテンツとは、ある一定期間は静的で、その後、変化するかしないかわからないタイプのコンテンツです。月に2回、年に1回、あるいは1時間に25回変化することもあります。重要なのは、前もってわからないということです。以下に、イベントドリブン型コンテンツの例をいくつか挙げます。

> **Wikiページ** - Wikiページは何週間も変更されないことがあります。そして、与えられたトピックについて得られる新しい情報に基づいて、複数のエディターが一度にページを急速に更新することがあります。

> **スポーツのスコア** - しばらくは一定ですが、あるチームが得点を決めると状況が変化します。変化のスピードは予測不可能で、例えばバスケットボールの試合とサッカーの試合ではスコアの変化のスピードが全く違います。

> **ニュース記事** - メディアサイトの記事もイベントドリブンであることが多く、特に頻繁に更新されている場合は、その傾向が強いです。

> **コメント** - ブログ記事やニュース記事にユーザーが投稿したコメントは、頻繁に変更されることが多いです。

> **在庫量** - 在庫の内容は短期間一定で、その後は予測不可能に変化することがあります。

> **株価** - 株価は短時間は一定で、頻繁に変化する（1日10時間以上全く変化しない時間を除く）。

> イベントドリブンに該当するコンテンツは多く、その静的な性質は予測不可能であるため、キャッシュできないと言われてきました。以前は、この種のコンテンツをキャッシュしようとすると、非常に小さなTTLを使用し、短期間とはいえ一定期間、陳腐化したコンテンツが存在する可能性があるという不安を抱きながらキャッシュしていました。

最後の"非常に小さなTTLを使用"はよく使われる手法です。例え60秒間に10,0000リクエストがあるページでも1秒の生存期間にしておくと10,0000リクエストの処理をする代わりに60回の処理で済むようになります。この戦略はトラフィックの高いサイトに対しては特に有効ですが、ロングテールのコンテンツに対して効果が薄くなります。

### イベントドリブンコンテンツのキャッシュ

> イベントドリブン型コンテンツのポイントは、予測不可能な静的状態であることです。ユーザーによるものであれ、サーバーによるものであれ、管理者によるものであれ、何らかのアクションがきっかけで変化します。いずれの場合も、コンテンツは変化します。しかし、興味深いのは、コンテンツが変更されると、アプリケーションがその変更について知る可能性が非常に高いという点です。つまり、イベントドリブンのコンテンツをCDNにキャッシュし、変更があった場合には、即座にプログラムによって「キャッシュ無効化」すればいいのです。

> 基本的に簡単なことのように聞こえますが、そうではありません。これを実現するためには、CDNは2つの中核的な機能を提供する必要があります。

> CDNは、オンデマンドで即座にコンテンツをパージする機能を備えている必要があります。コンテンツが変更されたら、CDN から即座に削除し、オリジンサーバーから再フェッチできるようにし、エンドユーザーが最新バージョンを見ることができるようにしなければなりません。

> イベントドリブン型コンテンツは新しいものではありません。この種のコンテンツはずっと以前から存在していました。この種のコンテンツを適切にキャッシュする仕組みがなかったため、従来のCDNは、この種のコンテンツを動的コンテンツと同様に扱い、キャッシュ不可能なものとして分類するよう教えてきました。しかし現在では、この種のコンテンツを適切にキャッシュするための適切なツールが実際に利用できるようになっており、真の意味で動的なコンテンツと区別することが重要であると考えています。


「**適切にキャッシュするための適切なツール**が実際に利用できる」状況に対して何ができるのかを考えべきだと考えました。

## 何ができる？

イベントドリブンのコンテンツを適切にキャッシュするために必要なこと。

* コンテンツを静的、動的、イベントドリブンと区別する
* イベントドリブンコンテンツのキャッシュ扱うためには、CDNのインスタントパージの機能が前提

加えて、アプリケーションはコンテンツの変更時にCDNのパージを行わなければなりません。コンテンツが変更された時にCDNに対して、そのコンテンツは無効になったとAPIで伝えます。その責務をアプリケーションが担う代わりにフレームワークが行えばより安全で、適切なキャッシュが行えると考えました。

次回はその仕組みをキャッシュをする場所に焦点を当てて説明します。