pig-mesh / multilevel-cache-spring-boot-starter Goto Github PK
View Code? Open in Web Editor NEWspring cache 多级缓存扩展
Home Page: https://pig4cloud.com
License: Apache License 2.0
spring cache 多级缓存扩展
Home Page: https://pig4cloud.com
License: Apache License 2.0
刚接触二级缓存,有时间能不能添加个使用示例?
有没有使用AOP能监测 org.springframework.cache 包下的操作类,来获取方法执行时计算出来的Key值?谢谢
如题,目前版本只支持 Caffeine,自定义支持 L1 和 L2,预计下周抽空完成。
虽然测试中出现的概率几乎为0,但是处理的逻辑确实有可能出现这种情况:
在代码逻辑中:
push(new CacheMessage(this.name, key))
caffeineCache.put(key, value)
push(new CacheMessage(this.name, key))在CacheMessageListener的回调方法中,并没有过滤掉当前节点,可能会导致当前节点的本地caffeine缓存也删除,当然,这个情况可以说几乎不存在(因为走网络和走内存几乎是走内存快),但是更加严谨的做法,应该是处理消息时,避开当前节点
目前版本中无法更改序列化方式,只能使用默认的jdk序列化方式,也无法自定义RestTemplate模版。
private void doPut(Object key, Object value) {
Duration expire = getExpire();
value = toStoreValue(value);
if (!expire.isNegative()) {
stringKeyRedisTemplate.opsForValue().set(getKey(key), value, expire);
}
else {
stringKeyRedisTemplate.opsForValue().set(getKey(key), value);
}
push(new CacheMessage(this.name, key));
caffeineCache.put(key, value);
}
在doPut方法中,默认不设置时间则采用全局过期时间,全局过期时间设置为0,默认不过期,但在这里走的是stringKeyRedisTemplate.opsForValue().set(getKey(key), value, expire);这条语句,导致报错。
@CacheEvict(value = {"tt1"}, allEntries = true)
原版会将所有value 为tt1 缓存全部删除,而0.03版本代码不会删除对应缓存
No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary or declare a specific CacheManager to use.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:224)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:914)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
cacheName:key1-key2-key3
(id-类型-数量)返回集合数据cacheName:key1-key2
(id-类型)更新一条数据cacheName:key1-key2
的缓存数据失效功能public <T> T get(Object key, Callable<T> valueLoader) {
....
ReentrantLock lock = keyLockMap.get(key.toString());
if (lock == null) {
log.debug("create lock for key : {}", key);
lock = new ReentrantLock();
keyLockMap.putIfAbsent(key.toString(), lock);
}
try {
lock.lock();
....
}
catch (Exception e) {
throw new ValueRetrievalException(key, valueLoader, e.getCause());
}
finally {
lock.unlock();
}
}
关于下方这几句是否有线程安全问题:
lock = new ReentrantLock();
keyLockMap.putIfAbsent(key.toString(), lock);
lock.lock();
假设线程T1、T2同时获取lock为null,且都进入了
if(lock == null) 方法体。
T1、T2分别执行了lock = new ReentrantLock(); 假设T1为lock1,T2位lock2。
接着T1成功把lock1放入keyLockMap,T2放入时就会失败。
再下方的代码lock.lock(),T1和T2分别拿着自己的lock同时执行了需要同步的代码块。
下面是我的认为的解决方法
public <T> T get(Object key, Callable<T> valueLoader) {
....
ReentrantLock lock = keyLockMap.get(key.toString());
if (lock == null) {
log.debug("create lock for key : {}", key);
lock = new ReentrantLock();
ReentrantLock templock = keyLockMap.putIfAbsent(key.toString(), lock);
lock = templock == null ? lock : templock;
}
try {
lock.lock();
....
}
catch (Exception e) {
throw new ValueRetrievalException(key, valueLoader, e.getCause());
}
finally {
lock.unlock();
}
}
按理说 cacheManage使用方式,用hash存储更契合,与caffeine里面的类型也更兼容
过期时间的问题,caffeine中设置的是整个cacheName的过期时间,而redis设置的是每个key的过期时间,是否会有问题呢
1.0.0版本
在spring boot actuator中
CaffeineCache 有专属的CaffeineCacheMetrics
希望RedisCaffeineCache也能提供
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.