kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

cacheの仕組みがわかっていません。どういう仕組みですか

個人的にcacheの仕組みを理解していないと思っている。

cacheをいれればパフォーマンスが向上する。といわれても理解度が低いため納得する材料が欲しい。特にデータベースについてはパフォーマンスのネックになることが多く、cacheを入れることで負荷軽減ができるのであればいれたい。

まずは具体的なキャッシュの動作を理解しておこうとおもいます。全て同じ仕組みではないと思いますが、例として具体的な動作がわかるとイメージしやすいため最初にやっておきます。

個人的理解度 phpコード

 
private $cache;

public function findById($id){
    return isset($this->cache[$id]) ?? $this->databaseFindById($id);
}

private function databaseFindById($id){
    $data = $repo->findById($id)
    $this->cache[$id] = $data;
    return $data;
}

一度検索したものにkeyを指定して保存、再度検索する際にはkeyによる結果を返す。どの値をkeyに指定するのかが重要で、どう保存・更新するかが重要な部分ですね。

laravel8でどう作られているか見る (view)

laravelでcacheが作られている仕組みを見てみる。

installしてsailでdockerを動かして確認してみる。

curl -s "https://laravel.build/example-app" | bash
cd example-app
./vendor/bin/sail up

sail upの段階でmysqlアーキテクチャでエラーが出たため、docker-compose.ymlのmysqlに「 platform: 'linux/amd64'」を追加

welcomeページを表示

storage/framework/cache/viewsにデータが追加された。内容を確認するとbladeの記法の部分をphpに変換しているらしい。

viewのCompiers/Compiler.phpをみると、pathをsha1で変換した文字列をkeyにしている。viewで指定した文字列がpathになっているみたい。

viewの場合はリリース時にファイルの内容が更新されると考えればリリース時にcacheをクリアすれば問題なさそう。

viewファイルについてはbladeの変換処理がなくなるため少し早くなる感じだと納得。微々たる変化かもしれないが大量のアクセスへの負荷を考えると効果はあるだろう。

laravel8でどう作られているか見る (database)

eloquentを使っていてもキャッシュされるわけではなさそう。明示的にキャッシュのコードを書く必要があるみたい。

Cache::put($key,$data, $minutes);
Cache::forever($key,$data);
Cache::get($key);
Cache::forget($key);

なるほど。自分でwhere句とかでキャッシュすればいいのね。登録や更新の際にはクリアすればいいのね。不具合の温床やん。

eloquent使ってる部分ならなんとかなるかもしれないけど、QueryBuilder使ってる部分まで考慮できる気がしないから難しい気がする。

少なくなるように工夫をする必要はありそう。

何個かしらべてみて、eloquentのイベントのsavedでキャッシュクリアを入れるのは良さそう。(finishSaveで呼び出ししてるしよさそう)

アプリケーションレベルの場合は、結構わかりやすい仕組みですね。

個人的に気になっているのはawsのrdsにキャッシュのサービスの説明が書いてあり、ミドルウェアレベルで実現できる内容が気になっている状態です。

このあたりがわからないので、もう少し調べてみます。

まとめ

動作を知るだけで使う時に納得できるのがいいですね。

あとはドキュメントはcacheデータは、memcachedとredisが早いよ。って書いてありますね。

The cached data is usually stored in a very fast data store such as Memcached or Redis.

まぁ、fileではやらないようがいいよね。分散化したときも大変そうだし。

参考

www.ritolab.com

qiita.com