EHcache是 Java最广泛使用的一种Cache. 它能高效的减轻数据库的负载,同时有很好的扩展,支持集群, 是解决C10K问题的一把重要利器. 它使用简单,高速,实现线程安全,同时提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时 ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统。
为什么需要Cache?
Cache主要是用来提高系统的吞吐量. Cache主要是用来缓存CPU使用过其它DNS 系统的数据. 很多时候CPU以本地引用的方式不断去重复请求同样的数据. 这个时候Cache相当一块有"记忆"能力的空间,如果它记得你需要的数据,就直接传给请求者,如果不记得这个数据,才会像其它DNS系统发出请求.
所以有可以得出Cache几点很重要的作用:
- 提高CPU的速度
- 提高IO
- 系统的更有弹性.
如何使用Cache?
cache-hit: 请求的数据在缓存空间存在.
cache-miss:请求的数据在缓存空间中不存在.
命中率 : cache-hit/(cache-hit+cache-miss)Cache的关键在于它的命中率, Encache提供了三种缓存清空策略:
FIFO:先进先出
LRU:最近最少使用
LFU:最近不经常使用
FIFO:最近一次创建或者更新的,将被清空.
public class FifoPolicy extends AbstractPolicy {
/**
* The name of this policy as a string literal
*/
public static final String NAME = "FIFO";
/**
* @return the name of the Policy. Inbuilt examples are LRU, LFU and FIFO.
*/
public String getName() {
return NAME;
}
/**
* Compares the desirableness for eviction of two elements
*
* Compares hit counts. If both zero,
*
* @param element1 the element to compare against
* @param element2 the element to compare
* @return true if the second element is preferable to the first element for ths policy
*/
public boolean compare(Element element1, Element element2) {
return element2.getLatestOfCreationAndUpdateTime() < element1.getLatestOfCreationAndUpdateTime();
}
}
LRU:
最近最少使用, AccessTime最老的会被清掉.
public class LruPolicy extends AbstractPolicy {
/**
* The name of this policy as a string literal
*/
public static final String NAME = "LRU";
/**
* @return the name of the Policy. Inbuilt examples are LRU, LFU and FIFO.
*/
public String getName() {
return NAME;
}
/**
* Compares the desirableness for eviction of two elements
*
* Compares hit counts. If both zero,
*
* @param element1 the element to compare against
* @param element2 the element to compare
* @return true if the second element is preferable to the first element for ths policy
*/
public boolean compare(Element element1, Element element2) {
return element2.getLastAccessTime() < element1.getLastAccessTime();
}
}
LFU: 最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存
public class LfuPolicy extends AbstractPolicy {
/**
* The name of this policy as a string literal
*/
public static final String NAME = "LFU";
/**
* @return the name of the Policy. Inbuilt examples are LRU, LFU and FIFO.
*/
public String getName() {
return NAME;
}
/**
* Compares the desirableness for eviction of two elements
*
* Compares hit counts. If both zero,
*
* @param element1 the element to compare against
* @param element2 the element to compare
* @return true if the second element is preferable to the first element for ths policy
*/
public boolean compare(Element element1, Element element2) {
return element2.getHitCount() < element1.getHitCount();
}
}
附上此处UML类图
使用场景一:
Hibernate配置Ehcache来缓存持久化对像,大幅度提高了系统的IO和吞吐量。
使用场景二:
作者在实现一个异步调用的RestService时,处理完用户的请求后,经常需要反向调用用户提供的Rest接口,向用户报告处理结果。这个时候我使用了Ehcache+Spring annotation的方式来缓存处理同一个接口的RestClientProxy对像。
使用场景三:
使用Ehcache集群,适合多结点轻量级Server或者做DR时,备份结点能实时backup主结点的内存数据。