この記事は?
この記事は アイスタイル Advent Calendar 2023/12/15の記事です。
こんにちは。アイスタイルで@cosmeの開発を担当しているエンジニアの村田です。今回は@cosmeでのキャッシュの使い方にも一部触れながら、キャッシュの使いどきと各層での使い方を解説します。
キャッシュの使いどき
キャッシュはいわゆる永続層とは異なり、データが揮発しても良い部分に使うようにします。キャッシュには適切なTTL(Time To Live)を設けることで適切な有効期限を設けるとともに、適切なタイミングで更新するようにします。また、キャッシュのサイズが大きすぎるとサーバーのメモリーを圧迫してしまい予期せぬ挙動となることもあるので、不要なキャッシュは残さないようにするほか、サイズだけではなく、キャッシュを行う粒度に関しても適切な設計である必要があります。運用の開始後は、エビクションやヒットレートなどの情報を収集しておくことで、実装したキャッシュが意図通りに使われているか監視を行うことができて便利です。
※エビクション: キャッシュのメモリーが飽和状態のとき、溢れた情報を削除する。どのデータを削除するかはエビクションポリシーに従う。
※キャッシュヒットレート: CPU内部のキャッシュメモリーに目当てのデータが存在する割合。必要なデータがないことはキャッシュミスという。
・DBサーバー
DBのキャッシュです。DBサーバーのキャッシュの代表的な仕組みの一つとして、バッファプールがあります。バッファプールを使うことで、アクセス頻度の高いデータページをメモリにキャッシュできるほか、インデックスのキャッシュに関しても行うことが可能です。データは構造が複雑で、規模が大きくなるほど検索に時間がかかるようになりボトルネックになるので、まずはDB層で的確にキャッシュで高速化を行なっておきたいです。
・APサーバー
開発エンジニアであればキャッシュと聞いてAPサーバーで行うキャッシュが最も馴染み深いのではないか?と思います。ここでは、@cosmeメディアのAPサーバーにおけるキャッシュを考えてみましょう。ログインの仕組みはセッションキャッシュで実現されます。レスポンスを返すところで、特にキャンペーンなどアクセスが集中すると大量のクエリが発行されてDBサーバーへの負荷になってしまうため、@cosmeメディアではMemcachedといったインメモリキャッシュを採用することでデータキャッシュを行い、DBサーバーへの通信による負荷を最大限防ぐようにしています。
・Webサーバー
Nginxは代表的なWebサーバーで、リバースプロキシとしてキャッシュの機能を持たせることができます。リバースプロキシでは、リクエストに対する応答をキャッシュに保存しておき、リクエストが来たときにキャッシュがないとAPサーバーに転送するような仕組みをとってキャッシュを実現しています。本丸のAPサーバーにリクエストを届ける前でキャッシュできる前座のサーバーであると言っているといっていいでしょう。
・CDNサーバー
CDNもキャッシュを行うサーバーですが、先ほど紹介したリバースプロキシとはキャッシュの機構が違うため、注意が必要です。CDNでは、キャッシュサーバーが配信を行い、キャッシュがない場合はオリジンサーバーまでデータを取りにいくことで配信を実現しています。そうすることで、コンテンツ配信の最適化を行うことができるのです。CDNは各地のエッジロケーションからデータを配信するので、地域最適化や高速化に対して適したものになります。
・API ゲートウェイ
APIゲートウェイはAPIの管理に関心を持つ層で、それぞれのAPIに対して統括を行うような部分です。API ゲートウェイは、APIリクエストの応答を一時的にキャッシュし、同じリクエストに対して返すことでキャッシュを実現できます。キャッシュをどれくらい保持するかに関してはTTL(Time To Live)によって適切な時間を設定するようにします。
・クライアントキャッシュ
クライアントキャッシュに関する代表的なものとして、ブラウザキャッシュがあるので、ここではブラウザキャッシュを中心に説明します。ブラウザキャッシュのうち強いキャッシュは、ブラウザがサーバーに再度リクエストを送ることなく、キャッシュされたコピーを使用するよう指示するもので、サーバーにリクエストを送った上でキャッシュコピー使用を指示する弱いキャッシュとは異なっています。こういった特徴から、強いキャッシュはバナーなどの静的な部分に、弱いキャッシュは変化がある動的部分のキャッシュに適しています。
・強いキャッシュ
Expires ヘッダー
Cache-Control ヘッダー
・弱いキャッシュ
Last-Modified ヘッダー
ETag ヘッダー
クライアントキャッシュは、使用端末上のストレージに保存されます。ストレージへの負荷を下げるためにも、不要なものは削除するようにしましょう。
終わりに
本記事では各層にあるキャッシュの仕組みを紹介してきました。キャッシュは、知識がバックエンド寄りであればRedisなどAPサーバーのキャッシュに、クライアントサイド寄りだとクライアント寄りのブラウザキャッシュなど濃淡がつきやすい印象ですが、各層で的確なキャッシュをすることで最適化を行いたいものです。それぞれの層でのキャッシュを組み合わせることによって、大規模リクエストにも耐えられる仕組みの実現ができます。
カジュアル面談
アイスタイルでは@cosmeを始めとした各種サービスを展開しています。Node.jsを使った開発、アイスタイルでの開発に興味を持たれた方は、ご気軽にカジュアル面談をお申し込みください。