ehcacheぼかし大量にキャッシュを削除する方法
前言
ご存知のように、encacheは今最も流行っているjavaオープンソースキャッシュのフレームワークで、構成は簡単で、構造がはっきりしていて、機能が強いです。注釈@Cachebaleにより、方法結果をキャッシュに素早く追加することができます。@Cacheevictを通じて指定されたキャッシュを素早く消去することができます。
しかし@Cacheevictの注釈はkey-valueを使っていますので、あいまいな削除をサポートしないと問題になります。@Cachebaleを使ってSpring EL表現に合わせて、同じ方法の複数のキャッシュを追加しました。
タスクを追加、削除すると、リストが変わります。その時は、listOfTask(*)を関連するキャッシュはすべて削除します。この時、キャッシュの中でどれぐらいキャッシュされていますか?関連する内容は、@Cacheevictを呼び出して逐次削除することはできません。
ehcache自身が支持できない以上、私達自身で実現するしかないです。
実現する
使用した注釈付加のキャッシュを考慮すると、削除キャッシュも注釈処理を使用して、開発の一貫性を維持することができる。注釈は開発者にとっても友好的です。そこで、ユーザー定義の注釈を使って、バッファをぼかしたり消したりすることを考えます。
まず、注釈CacheRemoveを定義します。
コメントの目的は、一括ぼかしでキャッシュを削除することです。次の二つの問題を考慮する必要があります。はどんな方式でマッチングしますか? どうやって一括でkey を削除しますか?
私が提示した処理方法は、最も簡単な処理方法だと思います。はどのような方法で曖昧にマッチングしますか? どのように大量にkeyを削除しますか?サイクルのすべてのkey、正則に合致するのを見つけたら を削除します。
最初にクラス名のCacheRemoveAspectを定義します。
カットポイントの定義が終わりました。次の重要シーンはカットの具体的な実現です。一般的には、キャッシュは添削の方法で実行された後に削除されます。だから@AfterReturning()を使って実現します。具体的な実現には次のようなことが必要です。ブロッキング方法における注釈 は注釈がCacheRemove であるかどうかを判断する。は、注釈が入ってくるkeyが配列であるため、各key をループ処理する。は、サイクルで各keyを作成し、すべてのキャッシュを巡回し、マッチングしたキャッシュ を除去する。
具体的な実現は以下の通りです。
締め括りをつける
全体の過程の構想は簡単で、いくつかのAOPの知識を使って必要な機能を完成しました。しかし、特定の除去部分コードは最適化を考慮することができる。一回のキャッシュの全部の循環を通して、除去すべきキャッシュを全部きれいに除去します。今のようにいくつかのキーがあると思っているのではなく、全部のキャッシュは何回も巡回します。具体的な実現は読者に自分で完成させます。皆さんの役に立ちたいです。私たちを応援してください。
ご存知のように、encacheは今最も流行っているjavaオープンソースキャッシュのフレームワークで、構成は簡単で、構造がはっきりしていて、機能が強いです。注釈@Cachebaleにより、方法結果をキャッシュに素早く追加することができます。@Cacheevictを通じて指定されたキャッシュを素早く消去することができます。
しかし@Cacheevictの注釈はkey-valueを使っていますので、あいまいな削除をサポートしないと問題になります。@Cachebaleを使ってSpring EL表現に合わせて、同じ方法の複数のキャッシュを追加しました。
@GetMapping("/listOfTask/{page}/")
@Cacheable(value = "BusinessCache", key = "'listOfTask_'+ #page")
public ResponseMessage<PageTaskVO> getTaskList(@PathVariable("page") String page) {
do something...
}
上記のコードは、ページごとにジョブ情報を取得するものです。EL式でパラメータの中のpageを取得し、キャッシュのkeyとして@Cachebaleを使ってehcacheのキャッシュに追加します。このとき、キャッシュにlistOfTask_が現れます。1,listOfTask_2,listOfTask_3このタイプのキーです。タスクを追加、削除すると、リストが変わります。その時は、listOfTask(*)を関連するキャッシュはすべて削除します。この時、キャッシュの中でどれぐらいキャッシュされていますか?関連する内容は、@Cacheevictを呼び出して逐次削除することはできません。
ehcache自身が支持できない以上、私達自身で実現するしかないです。
実現する
使用した注釈付加のキャッシュを考慮すると、削除キャッシュも注釈処理を使用して、開発の一貫性を維持することができる。注釈は開発者にとっても友好的です。そこで、ユーザー定義の注釈を使って、バッファをぼかしたり消したりすることを考えます。
まず、注釈CacheRemoveを定義します。
@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheRemove {
String value();
String[] key();
}
ここで、valueはehcacheと同様に、動作するキャッシュ名を定義するために使用される。keyは、複数のキャッシュキーを格納するための行列の正規表現です。名前をつけたCacheRemoveは分かりやすく、ehcache自身の注釈と衝突しません。注の定義はここまでです。続いて、注解が必要です。使うスプリングフレームは自然なので、AOPで注解をしたいと思います。コメントの目的は、一括ぼかしでキャッシュを削除することです。次の二つの問題を考慮する必要があります。
私が提示した処理方法は、最も簡単な処理方法だと思います。
最初にクラス名のCacheRemoveAspectを定義します。
@Aspect
@Component
public class CacheRemoveAspect {
@Pointcut(value = "(execution(* *.*(..)) && @annotation(com.example.CacheRemove))")
private void pointcut() {}
do something...
}
接面において接点を定義し、execution(*.*)&@annotation(comp.example.C.acheremove)を使用して、すべての注釈付きCacheRemoveが実行されることを表します。@annotationの値は注釈の全制限命名名です。カットポイントの定義が終わりました。次の重要シーンはカットの具体的な実現です。一般的には、キャッシュは添削の方法で実行された後に削除されます。だから@AfterReturning()を使って実現します。具体的な実現には次のようなことが必要です。
具体的な実現は以下の通りです。
@AfterReturning(value = "pointcut()")
private void process(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class);
if (cacheRemove != null){
String value = cacheRemove.value();
String[] keys = cacheRemove.key(); // key
List cacheKeys = CacheUtils.cacheKeys(value);
for (String key : keys){
Pattern pattern = Pattern.compile(key);
for (Object cacheKey: cacheKeys) {
String cacheKeyStr = String.valueOf(cacheKey);
if (pattern.matcher(cacheKeyStr).find()){
CacheUtils.remove(value, cacheKeyStr);
}
}
}
}
}
以上、ehcacheの曖昧な一括除去キャッシュの具体的な実現です。その中のBusiness CacheUtilsは自分のためにカプセル化したehcacheツール類です。主にキャッシュを取得し、キャッシュを取得し、キャッシュを除去し、キャッシュを追加し、すべてのキャッシュを表示するなどの正常な機能を実現します。コードは以下の通りです
public class CacheUtils {
private static CacheManager cacheManager = SpringContextHolder.getBean("ehCacheManagerFactory");
public static Object get(String cacheName, String key) {
Element element = getCache(cacheName).get(key);
return element == null ? null : element.getObjectValue();
}
public static void put(String cacheName, String key, Object value) {
Element element = new Element(key, value);
getCache(cacheName).put(element);
}
public static void remove(String cacheName, String key) {
getCache(cacheName).remove(key);
}
public static List cacheKeys(String cacheName){
return getCache(cacheName).getKeys();
}
/**
* Cache, 。
* @param cacheName
* @return
*/
private static Cache getCache(String cacheName) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
}
public static CacheManager getCacheManager() {
return cacheManager;
}
}
これにより、ehcache全体が曖昧な量でキャッシュを削除する機能が実現される。締め括りをつける
全体の過程の構想は簡単で、いくつかのAOPの知識を使って必要な機能を完成しました。しかし、特定の除去部分コードは最適化を考慮することができる。一回のキャッシュの全部の循環を通して、除去すべきキャッシュを全部きれいに除去します。今のようにいくつかのキーがあると思っているのではなく、全部のキャッシュは何回も巡回します。具体的な実現は読者に自分で完成させます。皆さんの役に立ちたいです。私たちを応援してください。