キャッシュという仕組みについて解像度を上げる

## はじめに
キャッシュってなんだっけ思ってしまったので改めて調べてみる。

普段からキャッシュは使っている(間接的に)しキャッシュという言葉も使っている。
が
直接的にキャッシュを使った開発まではしていないので
キャッシュに対する解像度が低いなーと感じた。

この記事を書く中で解像度を上げることができたらいと思う。
そのための記事です。

## キャッシュとは
>一度利用したデータや計算結果などを、一時的に保存しておくもの。

定義はこんな感じですかね。

よくキャッシュという言葉を使う場面としては
ブラウザの文脈で使うことがが多いと思う。
「キャッシュクリアしました?」「スーパーリロードしてくだい」「すみませんキャッシュクリアしてなかったです」
あるあるですね。

あれはurlに対して提供されるコンテンツをブラウザがキャッシュ(一時的に保存)しているというものですね。
そうすることで同じページにアクセスした際の読み込み時間が短縮されるというものですね。

## キャッシュのデータはどこに保存されるのか?
キャッシュは一時保存するものという定義だったが
それはどこに保存されるのか。気になった。

基本的にはメモリに保存するのが一般的らしい。

- メモリ(RAM)
- HDD
- SSD

キャッシュを使うことで高速化するのが目的なのでそらメモリに保存するよね。
実際にキャッシュを利用してwebアプリケーションを構築するという場合
キャッシュシステムを使うことになり
その対象としては[Redis](https://redis.io/)や[Memcached](https://memcached.org/)を使うのがよろしいっぽい。


## キャッシュにも種類があるらしい

### ブラウザキャッシュ

これはよく聞くやつですね。
>ウェブブラウザが自動的にウェブページのリソース（HTML、CSS、JavaScriptファイル、画像など）をローカルに保存するキャッシュです。これにより、ウェブサイトの再訪問時にこれらのリソースを再ダウンロードする必要がなくなり、ページの読み込み時間が短縮されます

### CDNキャッシュ
これもよく聞くやつですね。
>Content Delivery Network（CDN）は、地理的に分散したサーバーネットワーク上にコンテンツ（ウェブページ、ビデオ、画像）をキャッシュします。これにより、ユーザーに最も近いサーバーからコンテンツを配信できるため、配信速度が向上します。

各地域にあるエッジロケーションでコンテンツ(動画とか画像とか)をキャッシュして地理的に近い場所から配信してくれるというサービスですね

### アプリケーションキャッシュ?(ローカルキャッシュ?)呼称揺れある
これは自身のサーバー内のメモリに保存するよというやつですかね

### 分散キャッシュ
>複数のサーバーにまたがってキャッシュデータを管理するシステムで、大規模なアプリケーションやマイクロサービスアーキテクチャでよく使用されます。RedisやMemcachedなどのインメモリデータストアがこの目的で利用されることが多いです。

実際にキャッシュという仕組みを使って高速化を図ろうとうする場合
このアプローチを取ることが多そう。

### データベースキャッシュ
>データベースクエリの結果をキャッシュすることで、同じクエリが再度実行された場合に高速に結果を返すことができます。これは、データベースの負荷を軽減し、アプリケーションのパフォーマンスを向上させる効果があります。

これは知らんかった。
DBの設定をいじるとキャッシュ機能を使うことができるっぽい。
DBレイアーでキャッシュをするのかアプリケーションレイアーでキャッシュをするのか
検討余地ありそう。


他にもハードウェアの世界でもあるし
レイアーによっても色々あるっぽいですね
https://codeahoy.com/2022/04/03/cache-invalidation/

## DBレイアーによるキャッシュかアプリケーションレイアーによるキャッシュどちらを使うべきか

知見がないのでChatGPTに聞いてみた。

**DBレイアーでキャッシュをするかアプリケーションレイアーでキャッシュをするか
どちらがいいですかね**

=========================
データベース（DB）レイヤーでキャッシュをするか、アプリケーションレイヤーでキャッシュをするかは、アプリケーションの要件、アーキテクチャ、および目的によって異なります。どちらのアプローチが適しているかを判断するためには、それぞれの利点と制限を理解し、具体的な状況に応じて適切な選択をする必要があります。

### データベースレイヤーでのキャッシュ
**利点**

自動化:
多くのデータベースシステムは、内部的にクエリ結果をキャッシュする機能を提供しており、開発者が手動でキャッシュロジックを実装する必要がない場合があります。

透過性:
アプリケーションコードを変更せずに、データベースのパフォーマンスを向上させることができます。
一貫性の維持: データベース管理システムがキャッシュの一貫性を保証するため、アプリケーション側での複雑な一貫性維持のロジックを実装する必要がありません。

制限:
カスタマイズの制限: キャッシュ戦略のカスタマイズが限られており、すべてのユースケースに適しているとは限りません。
データベースへの依存: キャッシュの実装がデータベースに密接に依存しているため、データベースの変更や移行が困難になる可能性があります。

### アプリケーションレイヤーでのキャッシュ
**利点**

柔軟性と制御:
アプリケーションレイヤーでキャッシュを実装することで、キャッシュの粒度、期間、および無効化戦略を細かく制御できます。
パフォーマンスの最適化: よくアクセスされるデータや計算結果をアプリケーションレベルでキャッシュすることで、データベースへのクエリ回数を減らし、応答時間を短縮できます。
スケーラビリティの向上: 分散キャッシュシステム（例: Redis, Memcached）を使用することで、アプリケーションのスケーラビリティを向上させることができます。

制限:
複雑性の増加: キャッシュの一貫性を保つためのロジックをアプリケーション側で管理する必要があります。
開発と保守のコスト: キャッシュロジックの実装と保守には追加の労力が必要です。

### 結論
アプリケーションの特定のニーズに基づいて選択する必要があります。柔軟性と制御が重要である場合や、特定のキャッシュ戦略が求められる場合は、アプリケーションレイヤーでのキャッシュが適しているかもしれません。一方で、開発の簡素化を優先し、データベース自体のキャッシュ機能を活用できる場合は、データベースレイヤーでのキャッシュを選択するのが良いでしょう。また、これらのアプローチを組み合わせることで、最適なパフォーマンスとスケーラビリティを実現することも可能です。

=========================

なるほど
まずはアプリケーションの性質という材料によって検討する必要がありそうですね。

あとはチームの技術力によっても検討する必要ありそうですね、
DBレイアーでやる場合はDBに詳しい人がいないと終わる気がしますね。

アプリケーションレイアーでやる場合は
設計しっかりしておかないとソースコードがカオスになって終わる気がしますね。

個人的にはDBのことよくわからないのでアプリケーションレイアーでやって
小さくやっていきたいお気持ちですね。

## おわり
キャッシュという仕組みについて調べてみて少しは解像度上がった気がします。
キャッシュという仕組みはいろんなところで使われていて・使うことができて
使われている場所によって呼称が変わるんだなーという感じですね。

キャッシュ戦略?について考えて実際に設計するのとても大変そうですね
設計が終わったあと実際に開発する場合はその辺の設計は抽象化されて内部事情を意識せずに開発できると思いますが
設計しくじるとあっという間に技術負債になりそうだし難易度の高いテーマだなと思うので属人化してしまう可能性も高いとも思う。

とか考えるとやりたくなくなるけど
個人的にはすごくおもしろいテーマだなと感じました。

間違った解釈しているかもですが
気づいた人いればご指摘お願いいたします。


## 参考記事
- [キャッシュとは？ウェブサイト高速化で活用したい4つのキャッシュを知ろう](https://academy.gmocloud.com/wp/know/20160125/1584)
- [Brief Overview of Caching and Cache Invalidation](https://codeahoy.com/2022/04/03/cache-invalidation/)
- [laravelドキュメント キャッシュ](https://readouble.com/laravel/10.x/ja/cache.html)