EHcache是 Java最广泛使用的一种Cache. 它能高效的减轻数据库的负载,同时有很好的扩展,支持集群, 是解决C10K问题的一把重要利器. 它使用简单,高速,实现线程安全,同时提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时 ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统。
为什么需要Cache?
Cache主要是用来提高系统的吞吐量. Cache主要是用来缓存CPU使用过其它DNS 系统的数据. 很多时候CPU以本地引用的方式不断去重复请求同样的数据. 这个时候Cache相当一块有"记忆"能力的空间,如果它记得你需要的数据,就直接传给请求者,如果不记得这个数据,才会像其它DNS系统发出请求.
所以有可以得出Cache几点很重要的作用:
如何使用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主结点的内存数据。