如果一个计算非常耗时,每次获取都重新计算,会消耗很多额外的计算资源。对于这些耗时的计算结果,可以存储在缓存中,下次需要的时候,直接访问缓存中的内容,而不是再重新计算一遍。对于易变性还比较高的数据,可以设置数据有效期,一旦超过有效期,缓存数据被移除,触发重新计算。
下面来看看apache的缓存实现:java cache system。
元素是放入缓存中的对象,可以通过键来访问。
缓存是多个字典的集合,每个字典被称为region,每个region可以单独配置。比如一个region可以用来存放更新频率低的城市数据,另外一个region用来存放更新频率高的商品数据。
“auxiliary”是一个region可以使用的可选插件。核心辅助工具是索引磁盘缓存、TCP横向缓存和远程缓存服务器。
cache.ccf
# DEFAULT CACHE REGION
jcs.default=DC
jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.UseMemoryShrinker=false
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.default.cacheattributes.ShrinkerIntervalSeconds=60
jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLife=21600
jcs.default.elementattributes.IdleTime=1800
jcs.default.elementattributes.IsSpool=true
jcs.default.elementattributes.IsRemote=true
jcs.default.elementattributes.IsLateral=true
# PRE-DEFINED CACHE REGIONS
#jcs.region.testCache1=DC
#jcs.region.testCache1.cacheattributes=org.apache.commons.jcs.engine.Com#positeCacheAttributes
#jcs.region.testCache1.cacheattributes.MaxObjects=1000
#jcs.region.testCache1.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
#jcs.region.testCache1.cacheattributes.UseMemoryShrinker=false
#jcs.region.testCache1.cacheattributes.MaxMemoryIdleTimeSeconds=3600
#jcs.region.testCache1.cacheattributes.ShrinkerIntervalSeconds=60
#jcs.region.testCache1.cacheattributes.MaxSpoolPerRun=500
#jcs.region.testCache1.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
#jcs.region.testCache1.elementattributes.IsEternal=false
# AVAILABLE AUXILIARY CACHES
jcs.auxiliary.DC=org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DC.attributes=org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath=${user.dir}/jcs_swap
jcs.auxiliary.DC.attributes.MaxPurgatorySize=10000000
jcs.auxiliary.DC.attributes.MaxKeySize=1000000
jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000
jcs.auxiliary.DC.attributes.ShutdownSpoolTimeLimit=60
package xxl.mathematica.cache;
import org.apache.commons.jcs.JCS;
import org.apache.commons.jcs.access.behavior.ICacheAccess;
import org.apache.commons.jcs.engine.behavior.ICacheElement;
import java.util.Map;
/**
* @author zhangliangbo
* @since 2020/9/6
**/
public class Cache {
private static final ICacheAccess<String, Object> I_CACHE_ACCESS = JCS.getInstance("default");
/**
* 获取值
*
* @param key 键
* @return 值
*/
public static Object get(String key) {
return I_CACHE_ACCESS.get(key);
}
/**
* 获取最大空闲时间(超过最大空闲时间,值会被移除)
* 单位:s
* 默认值参考cache.ccf
*
* @param key 键
* @return 值
*/
public static long idleTime(String key) {
return I_CACHE_ACCESS.getCacheElement(key).getElementAttributes().getIdleTime();
}
/**
* 获取最大生存时间(超过最大生存空间,值会被移除,即使在最大空闲时间内被刷新)
* 单位:s
* 默认值参考cache.ccf
*
* @param key 键
* @return 值
*/
public static long maxLife(String key) {
return I_CACHE_ACCESS.getCacheElement(key).getElementAttributes().getMaxLife();
}
/**
* 匹配正则表达式的键值对
*
* @return 键值对
*/
public static Map<String, Object> match(String pattern) {
return I_CACHE_ACCESS.getMatching(pattern);
}
/**
* 放入值
*
* @param key 键
* @param value 值
*/
public static void put(String key, Object value) {
I_CACHE_ACCESS.put(key, value);
}
/**
* 放入值,带有效期
*
* @param key 键
* @param value 值
* @param idleSeconds 有效期
*/
public static void put(String key, Object value, long idleSeconds) {
I_CACHE_ACCESS.put(key, value);
ICacheElement<String, Object> element = I_CACHE_ACCESS.getCacheElement(key);
element.getElementAttributes().setIdleTime(idleSeconds);
}
/**
* 键不存在时放置
*
* @param key 键
* @param value 值
*/
public static void putNx(String key, Object value) {
I_CACHE_ACCESS.putSafe(key, value);
}
/**
* 清空缓存
*/
public static void clear() {
I_CACHE_ACCESS.clear();
}
/**
* 移除键
*
* @param key 键
*/
public static void remove(String key) {
I_CACHE_ACCESS.remove(key);
}
/**
* 获取缓存的大小
*
* @return 缓存大小
*/
public static int size() {
return I_CACHE_ACCESS.getMatching(".*").size();
}
/**
* 获取缓存的容量
*
* @return 缓存容量
*/
public static int capacity() {
return I_CACHE_ACCESS.getCacheAttributes().getMaxObjects();
}
}