EC-CUBEというECサイトフレームワークを使用している案件で、改めてキャッシュ周りを見直したので備忘録になります。
発端はDoctrine 1.xのときにキャッシュを削除する際に、前方一致で削除する、deleteByPrefixがなくなっていたことです。
キャッシュ周りの変更をまとめると下記になります。(英文まま)
## Cache Changes
- Renamed old AbstractCache to CacheProvider
- Dropped the support to the following functions of all cache providers:
- CacheProvider::deleteByWildcard
- CacheProvider::deleteByRegEx
- CacheProvider::deleteByPrefix
- CacheProvider::deleteBySuffix
- CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid
- CacheProvider::flushAll will remove ALL entries, namespaced or not
- Added support to MemcachedCache
- Added support to WincacheCachedeleteByXXXという関数が軒並み消えていたんですね。
Result Cacheを使用する際に、IDに接頭語を付けて、前方一致で管理していたものが使えないといった感じです。
まぁ、ID管理じゃなくて、きちんとCacheにnamespaceを付けて管理してねということですね。
namespaceごとにキャッシュクリア(deleteAll)したりできます。
今回は、Result Cacheに関して使い方を説明したいと思います。ほかのキャッシュ等の情報は下記参照。
Official(English)::doctrine-project -- Caching
SymfonyでResultCacheを使用できるように設定する
Official(English)::Configuration Reference -- Cache Driver
様々カスタマイズできますが、サンプルとして、Githubのものをそのまま使用します。
doctrine:
orm:
auto_generate_proxy_classes: false
metadata_cache_driver:
type: pool
pool: doctrine.system_cache_pool
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system上記をdoctrine.yamlに記載したら設定は完了です。
Result Cache を使用する
Result CacheはDQL queryの結果をキャッシュすることが可能です。DQL queryを作成することで、関連メソッドが使用可能になります。
// Case Repository (extends ServiceEntityRepository)
$qb = $this->createQueryBuilder('user')
->where('user.id = :id')
->setParameter('id', $userId);
$qb->getQuery()
->useResultCache(true, 600, 'UserInfo')
->getResult();getQuery()でDQL queryが作成された後、関連メソッドが使用可能になります。
ResultCacheに格納するためにuseResultCacheを使用しています。
https://doctrine2.readthedocs.io/en/latest/reference/caching.html
今回はまだnamespaceを指定していないので、namespaceが無いキャッシュが作成されます。
例えば、namespaceの指定なしで、deleteAllすると、namespaceが無いキャッシュがすべて削除されます。
Result Cache を削除する
ResultCacheを削除する方法です。delete($id)とdeleteAllがあります。
// Case Repository (extends ServiceEntityRepository)
$qb = $this->getEntityManager()->createQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->delete('UserInfo');上記例だと、IDがUserInfoのキャッシュが削除されます。簡単ですね。
さて、次は今回の私のテーマだった、ある特定のキャッシュだけをまとめて削除したい場合です。
doctrine1.xのときは、IDに接頭語を付けて、前方一致でdeleteByPrefix()で削除していました。
その方法は使えなくなったので、namespaceでキャッシュを管理します。
namespaceを使用してresultCacheを管理する
簡単に言えば、namespaceという箱を作ってあげるだけですね。そこにキャッシュを格納していきます。
複数プロジェクトがあったり、User用のキャッシュ、Admin用のキャッシュなど区分けしたいときに便利です。
// Case Repository (extends ServiceEntityRepository)
// use ResultCashe in namespace "User"
$qb = $this->createQueryBuilder('user')
->where('user.id = :id')
->setParameter('id', $userId)
->getQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');
$result = $qb->useResultCache(true, 600, 'UserInfo')
->getResult();
// DeleteAll namespace "User"
$qb = $this->getEntityManager()->createQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');
$cacheDriver->deleteAll();キャッシュドライバを呼び出し、setNamespace()でDQL queryに対してnamespaceを設定しています。
上記コードでdeleteAllを実行した場合、namespaceが「User」であるキャッシュ群が削除されます。
以上簡単ですが、resultCacheの使い方とnamespaceの設定の仕方についてまとめてみました。
細かいところは、文中で紹介したURLから見ていただいたほうがよいと思います。
Symfonyおすすめ書籍
あまり種類がないのと、そもそもフレームワークとして情報が膨大なので、入門でも結構読み応えがあります。
📦