Ehcache与Guava Cache的介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lusteiger/article/details/84850433

Ehcache和Guava Cache一样都是本地缓存,也同为很成熟的JVM级别的缓存,可以满足绝大多数情况的需求。下面分别介绍一下这两种缓存技术

Ehcache

Ehcache是一个用Java实现的使用简单,告诉,线程安全的缓存管理类库。Ehcache具有快速、简单、低消耗、依赖性小等特点,遵循Apache 2.0 license。官网http://www.ehcache.org/

主要特点

  1. 快速,简单
    过去众多测试已经证明Ehcache是最快的Java缓存之一,Ehcache的线程机制是为大型高并发系统设计的,不需要复杂的配置,API也已于使用,很容易部署上线和运行。
  2. 支持多种缓存策略
    提供LRU,LFU,FIFO的缓存策略。支持基于cache和基于element的过期策略,每个cache的存活时间都是可以设置和控制的。
  3. 缓存数据有两级
    内存和磁盘,因此无需担心容量问题。缓存在内存和磁盘存储可以伸缩到GB,在大内存的情况下,所有进程可以支持数百GB的吞吐,在单台虚拟机可以支持多缓存管理器,还可以通过terracotta服务器矩阵伸缩到数百个节点。
  4. 缓存数据会在逊尼基重启的过程中写入磁盘
    Ehcache是第一个引入缓存数据持久化存储的开源Java缓存框架,缓存的数据可以在机器重启后从磁盘上重新获得,可以根据需要使用cache.flush方法将缓存刷到磁盘上面,极大地方便了Ehcache的使用。
  5. 可以进行分布式缓存
    通过terracotta的缓存集群
    使用RMI,JGroups或者JMS来冗余缓存数据
    可靠的分发:使用TCP的内建分发机制
    缓存API:支持RESTFUL和SOAP两种协议,没有语言限制。
  6. 具有缓存和缓存管理器的侦听接口
    缓存管理器监听器
    缓存时间监听器
  7. 提供hibernate的缓存实现

适用场景

  1. 比较少的更新数据表的情况下
    Ehcache作为hibernate的缓存时,在进行修改表数据的时候,Ehcache会自动把缓存中关于此表的所有缓存全部删除掉,这样做只是能达到同步,但是对于数据经常修改的表来说,可能就失去缓存的意义了。
  2. 对并发要求不是很严格的情况下
    多台应用服务器中的缓存是不能进行实时同步的。
  3. 对一致性要求不高的情况下
    因为Ehcache本地缓存的特性,目前无法很好的解决不同服务器之间缓存同步的问题,所以在一致性要求高的场合,建议使用Redis,memcached等集中式缓存。

Ehcache的瓶颈点

Ehcache作为本地缓存能给我们带来使用便利和性能的提升,但是也存在一些瓶颈。

  1. 缓存漂移(cache drift)
    每个应用节点只管理自己的缓存,在更新某个节点的时候,不会影响到其他的节点,这样数据之间可能就不同步了。
  2. 数据库瓶颈
    对于单实例的应用来说,缓存可以保护数据库的读风暴;但是在集群环境中,每一个应用节点都要定期保持数据最新,节点越多,要维持这样的情况对数据库开销越大。

实际工作中的使用

通常在项目中使用集中式缓存(Redis或者memcached)通常都是先检查缓存中是否有存在期望的数据,如果有则直接返回,如果不存在则查询数据库然后将数据缓存,最后将结果返回。如果缓存系统因为某种原因宕机,造成服务无法访问,那么大量的请求将直接穿透到数据库,对数据库造成极大的压力。
针对以上情况,可以将Ehcache作为集中式缓存的二级本地缓存,这样缓存系统宕机后,服务器应用的本地缓存还能继续抗住压力。
但是使用了Ehcache作为二级本地缓存后,可能会存在本地缓存与缓存系统之间数据不一致的问题,因为本地缓存存在与服务器应用中,实际生产环境中必定是多台服务器分别部署,如何能够在更新缓存系统数据的同时,也能够更新Ehcache缓存数据,以及保证不同服务器间Ehcache本地缓存数据的同步问题。(案例中采用Redis缓存)
(1)方案一:定时查询
每台应用服务器定时轮询Redis缓存,比较缓存数据的版本号和本地Ehcache缓存的版本号大小,如果本地Ehcache的版本号小于Redis缓存的版本号,则获取最新缓存,同步更新本地Ehcache缓存,否则跳过本轮轮询。
缺点:每台服务器定时轮询的时间点可能不一样,那么不同服务器刷新最新缓存的时间可能也不一样,这样就会产生数据不一致的问题,对一致性要求不是很高的时候可以使用。
(2)方案二:主动通知
这种方案加入了消息队列,使每台应用服务器的Ehcache同步侦听MQ消息,通过MQ推送或者拉取的方式,在一定程度上达到同步更新数据。
缺点:因为不同服务器之间网速的原因,也无法达到强一致性。基于此原理使用zookeeper等分布式协调通知组件也是如此。

Guava Cache

Guava 是Google提供的一套Java工具包,而Guava Cache作为Guava的Cache部分而提供非常完善的本地缓存机制。Guava Cache是一个基于全内存的本地缓存实现,它提供了线程安全的实现机制。

Guava Cache的适用场景

  1. 愿意消耗一些本地内存空间来提升速度
    一些数据对一致性要求不高,就可以不用放到Redis等集中缓存中,这样频繁读取还会增加网络开销,同时也需要考虑集中缓存宕机的情况。
    在使用本地内存做缓存的时候,也需要考虑缓存的数据总量不能超过服务器内存,应该做一些数据淘汰机制来保障。
  2. 更新锁定
    当请求某一个key的时候,如果不存在则从源中读取,然后再回填到本地缓存中,这时如果并发量非常大,可能有多个请求同时从源中读取数据,然后再回填到本地缓存,造成多次执行的情况。
    Guava Cache可以在CacheLoader的load方法中加以控制,对同一个key,只让一个请求去源中读数据,而其他请求阻塞等待结果。在高并发场景中,这样虽然不会对后台服务造成压力,但其他所有请求都被blocked了。
    针对以上情况,Guava Cache提供了一个refreshAfterWrite定时刷新数据的配置项,刷新时只有一个请求回源取数据,其他请求会阻塞在一个固定的时间段,如果再这个时间内没有获得新值就直接返回旧值,这样请求就blocked情况就可控了。

缓存数据删除

1.被动删除
(1)基于数据大小的删除
(2)基于过期时间删除
(3)基于引用的删除
2.主动删除
单独删除,批量删除,删除所有数据

总结

总的来说,Ehcache适合支持持久化功能,有集群解决方案,而Guava Cache只是一个支持LRU的concurrentHashMap,没有Ehcache那么多特性,只支持增删改查,刷新规则和时效规则设定等最基本的设定,但是Guava Cache极度简洁又能满足大部分要求。

内容整理自于君泽,曹洪伟,邱硕等编著的《深入分布式缓存——从原理到实践》

展开阅读全文

没有更多推荐了,返回首页