キャッシュ戦略を考えた
はじめ
もっともっとキャッシュをうまく活用することでよりスケーラブルに、よりレスポンシブにしたいなーと考えていて幾つかのパターンを考えたのでまとめておこうと思う
キャッシュといえども広義になってしまうけどここではhtml全体をキャッシュさせてレスポンスさせるキャッシュを指して書きます
設計する上のでポイント
- ユーザ毎の情報をいかにキャッシュから返すか
- staticなデータはまぁ良いとしてユーザ毎のデータのキャッシュはしくると情報漏えいとなってしまい大事故になるので慎重に!!
- キャッシュをさせたくないデータ(ex:ECサイトだったら在庫数とか)をどう扱うか
考えたパターン
varnishを活用した場合
説明
- varnishはpostやget、urlによってキャッシュするしないという設定が柔軟で😃
- varnishの設定によりキャッシュさせるページ=データを設定する
- 図の流れのように順番に上からアクセスをさばくが、varnishの部分でキャッシュが存在していればそこからレスポンスされる
- なのでキャッシュがあればELB→Nginx→Varnishだけでレスポンスをする
- ESI(Edge Side Includes)とvcl-hashingの機能を使えばユーザ毎のデータも部分的にキャッシュ可能で効率的にキャッシュできる😃
- キャッシュのクリアは特定のIPからのcurlでrefreshする仕組みを作り、必要に応じてcurlする
Memcachedを活用した場合
説明
- まぁ手軽😃
- ngx_http_memcached_moduleを活用してキャッシュが存在すればレスポンスするようになる
- なのでELB→Nginx→Memcached→Nginxでレスポンスをする
- Module ngx_http_memcached_module
- ngx_http_memcached_module自体にはキャッシュさせる仕組みは無く、どのページ、どのデータをキャッシュさせるかはバックエンド=PHP側で行い、ngx_http_memcached_moduleはキャッシュがあればそのデータをレスポンスをする
- ただVarnishのようにユーザ毎のデータのキャッシュを作ってそれぞれにレスポンスする仕組みは整っておらず、ちょっと厳しい😂
- キャッシュのクリアはバックエンドからkeyを特定してmemcachedのデータをdeleteする
AWS CloudFrontを活用した場合
説明
- 前の2つとはちょっと毛色がかわる
- AWS CloudFrontを活用する
- Nginxで特定のURLの場合にリバースプロキシ設定でCloudFrontへ飛ばす
- CloudFrontのoriginにはバックエンドのサーバを指定してhtmlのキャッシュを作り、CDN配信する
- ユーザ毎に必要なデータはすべてAPI経由で配信する
- キャッシュのクリアはそもそもAPIから都度配信しているので考慮不要
最後
- 3パターン考えて見たけどCloudFrontにのせるとCDN配信されるのでインフラのグローバル対応にも役立つし(当然これだけではダメだんだけど)、手間いらずにスケーラブルだなーと感じた😃
- サービスを流行らせて、AWSを使い倒せばボリュームディスカウントhttps://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/useconsolidatedbilling-discounts.htmlが期待できるので良いかも
varnishを活用した場合
とMemcachedを活用した場合
のbenchmarkは下記の記事が参考になります😃 tsuyoshi-nakamura.hatenablog.com- 他にもよい方法あるのかなぁ...誰かあれば教えてください🙇🏽🙏