本地缓存ehcache、guava cache和Caffeine

在多线程高并发场景中往往是离不开cache的,需要根据不同的应用场景来需要选择不同的cache,比如分布式缓存如redis、memcached,还有本地(进程内)缓存如ehcache、GuavaCache、Caffeine。

一、ehcache

Java项目广泛的使用。它是一个开源的、设计于提高在数据从RDBMS中取出来的高花费、高延迟采取的一种缓存方案。正因为Ehcache具有健壮性(基于java开发)、被认证(具有apache 2.0  license)、充满特色(稍后会详细介绍),所以被用于大型复杂分布式web application的各个节点中。

什么特色?


1.  够快

Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.


2. 够简单

开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目

比如:hibernate


3.够袖珍

关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3  才 668KB。


4. 够轻量

核心程序仅仅依赖slf4j这一个包,没有之一!


5.好扩展

Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多


6.监听器

缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的



二、guava cache

先说说一般的cache都会实现的基础功能包括:

提供一个存储缓存的容器,该容器实现了存放(Put)和读取(Get)缓存的接口供外部调用。 缓存通常以<key,value>的形式存在,通过key来从缓存中获取value。当然容器的大小往往是有限的(受限于内存大小),需要为它设置清除缓存的策略。

在GuavaCache中缓存的容器被定义为接口Cache<K, V>的实现类,这些实现类都是线程安全的,因此通常定义为一个单例。并且接口Cache是泛型,很好的支持了不同类型的key和value。作为示例,我们构建一个key为Integer、value为String的Cache实例:

  1. final static Cache<Integer, String> cache = CacheBuilder.newBuilder()
  2. //设置cache的初始大小为10,要合理设置该值
  3. .initialCapacity( 10)
  4. //设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操作
  5. .concurrencyLevel( 5)
  6. //设置cache中的数据在写入之后的存活时间为10秒
  7. .expireAfterWrite( 10, TimeUnit.SECONDS)
  8. //构建cache实例
  9. .build();

据说GuavaCache的实现是基于ConcurrentHashMap的,因此上面的构造过程所调用的方法,通过查看其官方文档也能看到一些类似的原理。比如通过initialCapacity(5)定义初始值大小,要是定义太大就好浪费内存空间,要是太小,需要扩容的时候就会像map一样需要resize,这个过程会产生大量需要gc的对象,还有比如通过concurrencyLevel(5)来限制写入操作的并发数,这和ConcurrentHashMap的锁机制也是类似的(ConcurrentHashMap读不需要加锁,写入需要加锁,每个segment都有一个锁)。


三、Caffeine

Caffeine是使用Java8对Guava缓存的重写版本,在Spring 5.0或者Spring Boot 2.0中将取代,基于LRU算法实现,支持多种缓存过期策略。

那么为什么这么好的东西需要被淘汰呢,如果对于本地Cache有过深入研究的人应该知道LRU算法基本可以满足大部分的场景,但是很多人为了精益求精,基于LRU的算法,又在此基础上提出了一系列更好的,更有效果的淘汰策略。比如有ARC,LIRS和W-TinyLFU等都提供了接近最理想的命中率,他们这些算法进一步提高了本地缓存的效率。

Cache的目的就是缓存,如果在功能一样的情况下,最重要的突破就是性能了。从功能上来看GuavaCache已经比较完善了,基本满足了绝大部分本地缓存的需求。那么Spring5使用Caffeine来代替GuavaCache就是因为性能的问题了。

Caffeine的API的操作功能和Guava是基本保持一致的,并且Caffeine为了兼容之前是Guava的用户,做了一个Guava的Adapter给大家使用也是十分的贴心。 
当然Caffeine的调整不只有算法上面的调整,还有内存方面的优化以及一些实用的方法没有覆盖到。不过相信仅仅是上面提到的新特点就会让人们有心动的想法去尝试。



  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本实例的环境 eclipse + maven + spring + ehcache + junit EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开 源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。 优点: 1. 快速 2. 简单 3. 多种缓存策略 4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题 5. 缓存数据会在虚拟机重启的过程中写入磁盘 6. 可以通过RMI、可插入API等方式进行分布式缓存 7. 具有缓存和缓存管理器的侦听接口 8. 支持多缓存管理器实例,以及一个实例的多个缓存区域 9. 提供Hibernate的缓存实现 缺点: 1. 使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。 2. 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache 数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。 EhCache的分布式缓存有传统的RMI,1.5版的JGroups,1.6版的JMS。分布式缓存主要解决集群环境中不同的服务器间的数据的同步问题。 使用Spring的AOP进行整合,可以灵活的对方法的返回结果对象进行缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值