プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Web技術
  • 【Web技術】キャッシュ戦略
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Web技術】キャッシュ戦略

09.11

  • miyabisan2
  • コメントを書く

この記事は5分で読めます

ブラウザキャッシュ

サイトの閲覧中や再訪問時に自身のPCに保存されたキャッシュを使えます。インターネット越しにコンテンツをダウンロードする時間がなくなりサイト閲覧が早くなります。

ただ、閲覧者が少ないうちはこれだけで良いのですが、増えてくるとサーバーへのリクエストが増えてきてサーバー負荷が高まってしまいます。そのためにProxyやCDNのキャッシュの必要性が出てきます。

多くの場合は同じページを再訪問するケースなどが考えられます。CSS/JS/画像などをローカル端末にキャッシュして再訪問の際はそれを使用します。

近年は、ServiceWorkerなどの技術が登場してより細かく柔軟にブラウザキャッシュを制御できるようになってきています。

ローカルのキャッシュファイル

ファイルの種類などの情報が記載されています。

HTTPレスポンスヘッダ

ローカルのキャッシュファイルの末尾に含まれています。以下の情報が記載されています。

  • キャッシュの種類(shared or private)
  • ageヘッダ(すでに経路上にキャッシュされている場合に存在する)

ローカルにキャッシュされていたとしても必ずしもprivateなキャッシュだけではない。(sharedなキャッシュも含まれる場合もある。)

オリジンのキャッシュ(ゲートウェイキャッシュ、Proxyキャッシュ)

オリジン

配信元サーバー、一般的にはWebサーバーやアプリケーションサーバーなどが該当します。サーバーの代理でレスポンスを行う。

ゲートウェイキャッシュ

経路上のキャッシュということでCDNに役割は似ているが、構成的にオリジンサーバーの近くに配置することが多い。Proxyとオリジンを同一リージョンに配置することも多い。必須ではないので全てのサイトが導入しているわけではない。(CDNとローカルキャッシュのみでよしと判断しているサイトも多い。)

CDNと比較したゲートウェイキャッシュのメリット

CDNを利用してもキャッシュの一貫性を維持しやすい点

ストリーミングのようなすぐにデータが切り替わるようなデータの場合だと複数のCDNでそれぞれ異なったデータをキャッシュしてしまう可能性がある。オリジンの近くにゲートウェイキャッシュがあることで複数CDNで同じデータをキャッシュできるようになる。

Varnish(Varnish Cache)

キャッシュに強みを持つProxy用ソフトウェア。このソフトウェアの使い方を覚えればngnix、Apache Traffic Serverなど他のソフトウェアの設定方法などにも活かせる。

経路上のキャッシュ(CDNキャッシュ)

サーバーの代理でレスポンスを行う。

オリジンと配信先の中間地点にCDNサーバーを配置してあげれば距離が縮まるのでコンテンツのダウンロード時間は縮まります。

CDNとクライアントの距離だけでなくどのようなネットワーク経路を通るかも重要。ただこれに関しては、一般人はどうしようもないのでCDN業者に任せてしまうのが早いです。(多くの業者は品質の良いネットワークを利用しやすい仕組みを構築しているため)

CDNは、クライアントからのリクエストを出来るだけクライアントに近いサーバー(エッジサーバー)からレスポンスします。(最適経路を探すのに「DNS方式」と「IP Anycast方式」の二つの方式がある。)

代表的なCDNサービス

  • Akamai
  • Fastly

キャッシュの種類

privateキャッシュ

特定のクライアントのみが参照可能な性質を持つ。ユーザー情報を含んだAPIなど特定のクライアント向け。

sharedキャッシュ

複数のクライアントから参照可能な性質を持つ。サイトのロゴ、CSSなどの複数クライアントで共有できるキャッシュ。キャッシュは再利用されてナンボになるので、多数のクライアントで共有できるsharedキャッシュを積極的に使っていくことがキャッシュ戦略において重要。

キャッシュの格納場所ごとに使えるキャッシュ

privateキャッシュsharedキャッシュ理由
ブラウザキャッシュ○○ブラウザキャッシュは他端末から参照できないのでprivate/sharedどちらもいける。
CDNキャッシュ基本的に✖️○他のユーザー間で共有可能なものであればprivateもキャッシュして良いが基本はNG
proxyキャッシュ基本的に✖️○他のユーザー間で共有可能なものであればprivateもキャッシュして良いが基本はNG

キャッシュ対象

静的ファイル

CSS/JS/画像ファイルなどのことですね。CPU負荷はかからないですが、これをキャッシュするすることも意義はあります。オリジンとは離れた場所にコピーを持てるので利益があります。オリジン側のサーバーリソースを使わなくてすみます。

特徴

  • TTLを長く設定できる。
  • 明確にTTLを決められる。

具体的に言えば、1時間が一つの目安。何なら1時間以上に設定してもそこまで問題になりません。

具体例

  • CSS
  • サムネイル画像

動的ファイル

PHPなどで動的に生成されたファイルのことですね。基本はこちらがキャッシュ対象になります。AppサーバーへのCPU負荷がかかるのはこちらのため。

特徴

  • 明確にTTLが決められない。
  • ユーザーの状態(例:ログイン、非ログインなど)で動作が変わる。

例えば、ニュースサイト、株価など頻繁に情報が変わるページの場合はどれくらいの時間キャッシュしたら良いかわかる人はいないでしょう。仮に設定するとしてもごく短時間になります。

上記のように静的ファイルに比べてTTLでキャッシュすることは難しいのですが、オリジンへの負荷を考えるとできればキャッシュしたいところです。

同じページないでもライフサイクルが異なるので、ライフサイクルが長めのものはTTLキャッシュして短めのものは諦めるみたいな感じで良いかと思います。(例えば、ブログのログイン後の画面でタイトルは一度設定したらなかなか変わらないですが、ブログの投稿内容は頻繁に更新が入ります。)

キャッシュの管理方法

ユーザーのローカルキャッシュ

強制的に消すこともできるがあまり望ましくない。TTLなどの設定で自然と使えなくなることが望ましい。

CDNキャッシュ

Akamaiなどではキャッシュ消去画面などが存在する。Akamaiなら数秒レベル、Fastlyならミリ秒単位の速度でキャッシュを削除することが可能です。(ここまで高速だと例えばゲームのマニフェストを更新があったら削除するみたいな運用に加える会社も出てくるレベルです。)

キャッシュは消えるもの

  • キャッシュサーバーの不具合による入れ替え
  • キャッシュサーバーの設定更新で既存キャッシュが使えなくなる。
  • サイト更新やアプリケーションの不具合対応などでキャッシュを消す。

キャッシュをすることでサーバーの負荷対策を行えますが、上記のようなケースでは消えるのでその辺の注意も必要です。

キャッシュを消してしまうとオリジンに対してリクエストが急増するので注意が必要です。もし何らかの理由で大量に消す必要が発生した場合は、数回に分けて消すなどの対策をとることもできます。

逆にキャッシュを消したいケース

基本的には安易なキャッシュ消去には頼らない運用が望ましいです。TTLを適切に設定することでコントロールできるようにする運用が望ましいです。(例:TTLを300秒と短めに設定しておくなど。再検証のアクセス数は長めに設定する場合に比べて増大するがあくまで再検証アクセスなので許容とするなど)

代表例:画像などの大元のコンテンツリソースを更新した時先にあげたキャッシュが残ってしまっていて急ぎで入れ替えたい時

Cache Busiting

クエリちゅうに更新日時などを入れてURLを変更することでキャッシュキーを変えるCache Busitingという手法があります。

1
2
3
http://xxx.com/bar.jpg?h=202309231010
↓
http://xxx.com/bar.jpg?h=202309231020
メリット

ローカル、経路上全てのキャッシュにおいて反映される便利な方法

デメリット

以前に参照していたキャッシュは残ってしまうので変更前のコンテンツも直接URLをリクエストすることで参照できます。なので、画像投稿サイトなどを運営していて著作権違反の画像が投稿された際に消さなければならない時にキャッシュが残ってしまうと困ります。(確実にキャッシュを消す必要がある)

キャッシュストレージ

全てのコンテンツがキャッシュストレージに収まるというのは実運用ではあり得ないです。限られた容量をうまく使ってシステム全体の負荷を減らすことを考えることが重要です。

キャッシュがいっぱいになった場合は、既存キャッシュを追い出す必要があります。削除対象はLRUやLFUのアルゴリズムで決定する方法はありますが、どちらかと言えばアルゴリズムよりはアクセス頻度だったり、生成コストなどが重要だったりします。特性ごとにキャッシュストレージ領域を分けるのが得策でしょう。

特性の種類

生成コスト

オリジンの生成コストなども考慮する。

リクエスト/ヒット特性

リクエストが殺到するが一定期間のみのもの、あまりアクセスがないもので分ける。

コンテンツサイズ特性

テキストはさほど大きくないが、画像は大きいです。サイズごとにキャッシュ空間を分けた方が良いです。でないと大きい容量がキャッシュされると一気に大量に押し出されることになります。

ストレージ特性

高速なストレージは高価だったりするので重要度によって変えること。

スポンサーリンク
  • 2023 09.11
  • miyabisan2
  • コメントを書く
  • Web技術
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 05.27

    ファイルの「圧縮」と「アーカイブ」と「解凍」、gzip圧縮について

  2. 2021 07.31

    【Web】「CORS」を使わないSOPの緩和方法

  3. 2023 09.14

    【Web技術】CDNについて

  4. 2021 07.31

    【Web】同一生成元ポリシー(SOP)について

  5. 2021 09.17

    【Web開発】「Data URL Schema」と「Blob URL Schema」の違い

  6. 2023 09.16

    【Web技術】画像の遅延読み込み(lazyload)について

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【React】カスタムフックについて

【Web技術】高速配信の戦略

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー