kenju's blog

About Programming, Mathematics, Security and Blockchain

Webアプリケーションにおけるキャッシュ戦略の比較

Webアプリケーションを高速化する際に、数々のレイヤーでキャッシュを適用することはよくある。この記事では、それぞれのレイヤーごとのキャッシュ戦略について、簡単な利点・欠点をリストアップし、比較する。

なお、実際にキャッシュを利用する場合は、更に「Redis/memcachedの違いは何か」など突き詰めて検討する必要がある点に注意。

キャッシュを利用するための三大原則

1. 計測すべし

ボトルネックのチューニングに労力をかけるべきで、影響の小さい箇所のパフォーマンスの最適化をしても意味がない。計測してボトルネックを明らかにしてから

2. キャッシュ以外の選択肢と比較すべし

キャッシュを利用する前に、アルゴリズムの最適化を検討して計算量を減らしたり、N+1クエリをエラしたりなど、キャッシュ以外の選択肢で改善できないかを検討するべき

3. キャッシュの削除について十分に検討すべし

キャッシュの有効期限はどれくらいの長さにするか、削除のフローはどうするかなども考慮すること

戦略一覧

  • クライアントレベル
    • ブラウザの提供するAPI(Service Worker)
  • ミドルウェアレベル
    • Redisやmemcachedなどのキャッシュストアを用いる
  • アプリケーションレベル
    • フレームワークの提供するキャッシュ機構を用いる
  • インフラレベル
    • CDNを用いる

比較軸

  • 開発時
    • 保守性・可読性
    • エラー発生リスク
    • 実装コスト
    • 拡張性・変更に対する柔軟性
  • 実行時
    • メモリ消費量
    • オーダー(計算量)
    • 実行時間
    • セキュリティ
  • 実際の挙動
    • 金銭的コスト
    • ユーザー体験
    • キャッシュの破棄の仕様(頻度・必要性)

利点・欠点

  • クライアントレベル
    • 利点
      • ブラウザに一番近いため、数ある選択肢の中で一番速くキャッシュしたコンテンツを提供できる
    • 欠点
      • 自由に改ざんできるためセキュリティリスクがある
      • サーバーサイドからの任意のタイミングでキャッシュのパージができない
  • ミドルウェアレベル
    • 利点
      • 機能が豊富なミドルウェア(例:Redis)を利用すれば、単純なキャッシュのためのKVSとしてではなくランキング機能など様々な用途にも利用できる
    • 欠点
      • 追加でミドルウェアを管理するコストが発生する
  • アプリケーションレベル
    • 利点
      • フレームワークがAPIを提供している場合、追加のコスト無しに気軽に利用することができる
    • 欠点
      • アプリケーションのコードにキャッシュのロジックが含まれるため、保守性・メンテナンスコストが若干あがる(= 乱用すべきではない)
      • キャッシュできるコンテンツは、フレームワークの提供するAPIに限定される
      • アプリケーションサーバーへのメモリ負荷が高まる
        • ただし、フレームワークの実装による(TempfileなどDisk I/Oを利用している場合もある)
  • インフラレベル
    • 利点
      • アクセスしてきたユーザーに対して地理的に近いサーバーからコンテンツを配信できる
      • キャッシュコンテンツの配信というアプリケーションサーバの責務が減るため、サーバーの負荷が下がる
    • 欠点
      • オリジンサーバーからエッジサーバーまで完全にキャッシュをパージしきるまで、タイムラグが存在する
      • 他の選択肢と比較して金銭的コストが掛かる傾向にある
      • 秘匿性の高い情報は、外部SaaSを使い場合CDNを利用できない場合がある
        • 自前でCDNを構築するコストを払うか、別の手段でキャッシュする必要がある