cache
素晴らしいblog
Stale-While-Revalidate ヘッダによるブラウザキャッシュの非同期更新(これが基本からわかりやすい)
システムにおいてキャッシュの設計は、永遠の課題でありWebのパフォーマンスにおいても非常に重要。
WebはHTTPヘッダーを用いてブラウザやプロキシにキャッシュの制御を指定する。
Stale-While-Revalidateヘッダーは、このキャッシュ制御に選択肢を追加する新しい仕様。
Cache設計の難しいところ
キャッシュは、「再利用」を行う目的でありながら、ある一定の範囲で「更新」を行いたいという、相反するコントロールが求められる。(キャッシュ設計のもっとも難しい点はここ)
キャッシュに関わるヘッダーや機能は他にもある点、そしてブラウザは独自の判断でキャッシュを使う場合があることに注意する。
Cache保存単位
ブラウザのキャッシュは基本的にURL単位で行われるため、URLが変わればキャッシュが変わる。
そのためこういうのをよくしていた
<script src="production.min.js?ver=1"></script>
↓
<!-- ver2に変える -->
<script src="production.min.js?ver=2"></script>
注意点がある。
ただし、この <script>
を含む index.html
自体が長期間キャッシュされてしまうと、 production.min.jsのURLも更新できない。
したがって、 index.html自体は長期間のキャッシュがしにくいという問題は残る。
Webにおけるキャッシュを指定するところ
Webでは、HTTPヘッダーを用いて
- ブラウザ
- プロキシ
にキャッシュの制御を指定する
キャッシュ制御が重要な理由
キャッシュを行う意義は大きく2つある。
- リソースの取得を高速化する
- サーバへの負荷を減らす
ブラウザーキャッシングは、リソースを保存してインターネット上のユーザー体験を向上させる優れた方法ですが、キャッシュを制御しないと、非常に脆化する恐れがある。
すべてのサイトのすべてのリソースは、同じキャッシュルールに制約されています。
つまり、機密情報は公開情報と同じ方法でキャッシュされ、頻繁に更新されるリソースは、めったに変更されないリソースと同じ期間だけキャッシュされます。
Webにおけるキャッシュ
歴史としてはHTTPヘッダーを用いてキャッシュを管理させる方法を用いてきた。
Webにおけるキャッシュの指定には大きく2つの方式がある。
-
ブラウザはリクエストを発行せず、保持するキャッシュを使用する
Cache-Control, Expires
-
ブラウザはリクエストを発行しサーバにキャッシュの有効性を確認してから、キャッシュを使用する
ETag, Last-Modified
Etag, Last-Modified
HTTPには、Conditional GET(条件付きGET)という仕組みがある。 これは、「すでに保持しているキャッシュが今でも有効かどうか」をサーバに問い合わせる方法。
具体的には、サーバは ETag, Last-Modified
などのヘッダーをレスポンスに付与することで、リソースに関する情報をクライアントに伝え、クライアントはその情報を次のコンテントネゴシエーションに利用し、キャッシュの再利用可否などを判断する。
Etag
そのリソースを一意に特定する値、要するにリソースのハッシュ値
Last-Modified
そのリソースが最後に更新されたタイムスタンプ。この値を保存したブラウザは、同じURLへのリクエストに、キャッシュしたリソースに付与されていた値を設定してサーバに問い合わせる。 サーバは、リクエストされたリソースについて各値を検証する。
cacheの種類
静的サイトだけでなくWebサイトに対するキャッシュとしては、大きく分けて下記の二種類のキャッシュがある。
-
サーバサイド CDNキャッシュ データベースキャッシュ ※注意点 CDNのキャッシュは管理者(サイト運営者)側で削除できる。
-
クライアントサイド cookie ブラウザのローカルキャッシュ ※注意点 CDNのキャッシュは管理者(サイト運営者)側で削除できるが、ブラウザのローカルキャッシュは削除できない。 ブラウザのローカルキャッシュはサイトを閲覧しているユーザの端末に保存されるキャッシュなので、ブラウザのスーパーリロードを実施してもらったり、その他の方法でキャッシュを削除してもらうようユーザに依頼する必要があります。
ブラウザローカルキャッシュさせない
ブラウザのローカルキャッシュを保存させないようにするためには、レスポンスヘッダーに Cache-Control
でキャッシュの動作を指定する必要がある。
cacheするコンテンツ・データの種類
キャッシュするコンテンツ・データにも下記のような種類がある。
- html
- css, js
- 画像データ それぞれキャッシュが残っていることで古い情報が表示され続けていたり、表示が崩れていたり、ボタンなどの動作が正しくなかったりといったことが起こる。 場合によってはコンテンツ・データの種類によってキャッシュ戦略を変える必要も出てきます。
Cache-Controlとは
Cache-Controlは、ブラウザーのキャッシュ動作を管理するHTTPヘッダーのこと。 簡単に言えば、誰かがWebサイトを訪問するとブラウザーはキャッシュと呼ばれるストアに画像やWebサイトデータといった特定のリソースを保存します。 そのユーザーが同じWebサイトを再度訪問すると、Cache-Controlは、そのユーザーにローカルキャッシュからリソースを読み込ませるか、またはブラウザーがサーバーに新しいリソースを要求する必要があるかを決めるルールを設定します。Cache-Controlをより深く理解するには、ブラウザキャッシュおよびHTTPヘッダーの基本を理解する必要があります。
cache-control: max-age このディレクティブは、ダウンロード後にキャッシュからリソースを提供できる秒数、つまり寿命を指示する。 たとえば、最大寿命が1800に設定されている場合、リソースをサーバーへ最初に要求してから1,800秒(30分)
ブラウザーキャッシュ
ブラウザーキャッシュは、WebブラウザーがWebサイトのリソースを保存することでサーバーから再度取得しなくても済むようにするもの。 たとえば、Webサイトの背景画像はキャッシュとしてローカル保存されるため、ユーザーがそのページを再度訪問したときに、画像はユーザーのローカルファイルから読み込まれるのでページ読み込み速度はずっと速くなる。
そうしたリソースをブラウザーはTime To Live(TTL)と呼ばれる一定期間だけ保存します。 ユーザーがTTLの期限が切れた後でキャッシュされたリソースを要求した場合、ブラウザーはサーバーに再度アクセスしてリソースの新しいコピーをダウンロードしなければならない。 ブラウザーとWebサーバーは、各リソースのTTLをどのように見分けるのでしょうか?ここで登場するのがHTTPヘッダーです。
cacheの重要性
Webサービスの応答速度を向上させることにより、ユーザー体験向上につながる。 実際に40%以上のWebサービスのユーザーはページの読み込みを3秒以上待てないという調査結果がある。
クラウドコンピューティングを利用し、Webサービスを提供する場合の読み込み遅延の要因は次の3つ。
- クラウドのデータセンター内での処理遅延
- エンドユーザーとデータセンター間のネットワーク転送遅延
- ブラウザ上でのコンテンツ表示遅延
過去のcache
Webサービスを提供する企業は、Akamai・CloudFrontなどの事業者が提供するCDN(Content Delivery Network)を以前より活用し、画像や動画などの静的コンテンツの配信を高速化してきた。
最近のcache
近年では、一度キャッシュされたデータを破棄するまでの処理時間が高速化したことにより動的コンテンツのキャッシュにもCDNを利用することがある。 さらには、単なるキャッシュを配信するだけでなく、CDNのエッジサーバ上で要求に対して任意の処理を実行できるように、エッジサーバに任意のアプリケーションを配置することが可能となるCDN Edge Workerと呼ばれるサービスが登場している。
プログラミング言語処理系の制約があるものの、CDN Edge Workerとしては、AWS Lambda@Edge2・Cloudflare Workers3・fly.io4などがある。
動的コンテンツに対するCDN
すべてのエッジでキャッシュが無効化されるまでに遅延があり、キャッシュ間またはキャッシュとオリジンのデータ間の一貫性が弱いという課題がある。 CDN Edge Workerにおいてもアプリケーションの配置は可能であるが、データの一貫性については厳密に保証するデータストアが提供されているわけではない。
エッジコンピューティング
CDN以外にも、エンドユーザーとクラウドのデータセンターの間に中間層を設けることにより、ネットワークレイテンシを最小化するエッジコンピューティングが研究されている。 エッジコンピューティングの研究分野では、IoT (Internet of Things)。スマートシティ、仮想現実などの従来のPCやスマートフォン以外のエンドデバイスを活用するような新しいコンピューティングへの適用が主目的となっている。
分散キャッシュの関連技術
Webアプリケーションの読み出し性能を向上するためのキャッシュの要素技術を整理し、その特徴を列挙する。 要素技術として、オブジェクトキャッシュ・クエリリザルトキャッシュ・HTTPキャッシュ・ICN(Information-Centric Networking)がある。
オブジェクトキャッシュ
オブジェクトキャッシュはアプリケーションが任意のオブジェクトをキャッシュするための機構。 オブジェクトキャッシュのためのデータストアとして、
- アプリケーションプロセスがネットワーク通信して利用するネットワーク型の分散キャッシュシステム
- アプリケーションプロセスと同一のメモリ空間にキャッシュデータを保持する組み込み型の分散キャッシュシステム
- ネットワーク型の分散キャッシュシステム
Memcached
やRedis
が広く利用されている。 これらのキャッシュシステムを複数のキャッシュノードへ負荷分散するために、ハッシュ法を利用することによりオブジェクトのキーと分散先のキャッシュノードを紐付けし、オブジェクト単位で分散させてキャッシュノードへデータを配置する。 この手法は、キャッシュノードの追加または削除時にオブジェクトのキーとノードの紐づけが変更され、大部分のキーを再配置することにより性能が低下するという課題をもつ。 そこで、ノードの追加・削除時にオブジェクトのキーとノードの割り当てをなるべくかえずに、分散するためにコンシステントハッシュ法が利用される。
クエリリザルトキャッシュ
参考URL データベースミドルウェア層でキャッシュする場合、DBへのクエリの結果をキャッシュするクエリリザルトキャッシュを利用する。 MySQLのクエリリザルトキャッシュは、DBサーバ自体がキャッシュ機構をもつため追加のソフトウェアなしにクエリリザルトキャッシュを利用できる。 テーブルに更新があれば当該テーブルの変更が結果に影響するクエリのキャッシュを破棄するため、テーブルとキャッシュ間で一貫性を維持する
静的サイトのキャッシュ戦略
静的サイトでは、その名の通りデプロイ時以外にコンテンツ情報が更新されることはないため、できる限りキャッシュの恩恵を受けることが望ましい。 そのため、基本戦略としてCDN/ブラウザともにキャッシュ時間は長くしておくのがよい。
ブラウザからキャッシュヒットしているか確認する(Chrome)
CloudFront利用時に、キャッシュヒットしているか/どのくらいの時間キャッシュされているかを確認する
- キャッシュの確認をするときに確認するHTTPヘッダー x-cache age
x-cache キャッシュヒットしたかどうかを判断できる。
age キャッシュされてからの経過時間。
- キャッシュの設定で利用するHTTPヘッダー Cache-Control Expires
Expires レスポンスヘッダーにのみ設定される。 キャッシュをいつまで有効とみなすか日時を指定する。
SWR(Stale-While-Revalidate)
Stale-While-Revalidate ヘッダによるブラウザキャッシュの非同期更新(これはすごい) Stale-While-Revalidateに関するメモ
HTTP RFC 5861で提唱された、SWRというキャッシュ無効化戦略
メモリキャッシュ or キャッシュメモリ
キャッシュメモリとは、CPUとメインメモリ(主記憶装置)の間にある記憶装置のこと。
CPUはアクセスする頻度の高いデータや命令をキャッシュメモリに保存しておく。
メインメモリよりもCPUに近い位置でキャッシュメモリからデータや命令を読み込むことでメモリアクセスの時間を短縮できるので、CPU性能の向上につながる。
以前はCPUのチップの外部にキャッシュメモリを搭載するのが主流でしたが、半導体微細化技術の向上により、現在はCPUのチップ上にキャッシュメモリを搭載しています。 キャッシュメモリのオンチップ化により、CPUからのアクセス距離がさらに短くなり、データの読み込み、書き出し処理を高速に行うことができます。 なお、現在多くのキャッシュメモリはSRAMと呼ばれる記憶素子で構成されています
フロントエンジニアが知るべきキャッシュ
インメモリキャッシュ
ChromeやFirefox、Safariなど世の中で利用されているブラウザにはインメモリなキャッシュがある。
インメモリキャッシュはRAMに保存されるため、書き込みとアクセスが高速になりますが、コンピューターの電源がオフになるか、その他の特定の状況で消去されます。このインメモリキャッシュは、各ブラウザのRendererプロセスに存在しています。