`
QING____
  • 浏览: 2255794 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

guava cache与编程实践

    博客分类:
  • JAVA
 
阅读更多

Guava-cache

    guava cache是google开源代码库中的一个辅助功能模块,可以作为JVM嵌入式cache来使用,基于key-value模型。对于Rdedis、Memcached,这种缓存系统,我们称之为“分布式缓存”,它们通过集群扩容,可以将海量数据cache在远端。而guava cache,作为“嵌入式cache”,这些cache的数据寄宿在当前JVM堆中,和JVM进程具有共同生命周期。它具备如下特点:

  • 占用JVM内存,内部数据结构类似于ConcurrentHashMap。
  • 因为JVM堆大小的限制,guava cache只能保存较少的数据量,不能超过JVM Heap。
  • 相对Redis等“分布式缓存”,它本身不需要RPC调用,性能较高。

    如果你的系统中,有一种数据符合“尺寸较小”、“高频的读取操作”、“变更操作较少”,那么使用guava cache这种“嵌入式缓存”,将非常适合,它将会带来巨大的性能提升。

 

    Guava cache读取过程也符合“get-if-absent-compute”语义,即如果本地缓存中有,则返回对应value,如果key不存在,则通过“加载机制”获取新的value。

  • 通过Cache.put相关方法,将key-value加入缓存。
  • 通过Cache.get,从cache中获取key对应的value。
  • 通过Cache.invalidate,将key-value通缓存中移除。

 

CacheBuilder:用来构建Cache,可以在构建时指定一些全局的参数。

CacheBuilder cacheBuilder = CacheBuilder.newBuilder()
                .concurrencyLevel(Runtime.getRuntime().availableProcessors() - 1)
                .initialCapacity(1024);
//maxCacheSize由外部注入,表示cache中保存的key的最大条数
if(maxCacheSize > 0) {
	cacheBuilder.maximumSize(maxCacheSize);
}else if(maxKeysWeight > 0) {
//maxKeysWeight由外部注入,逻辑上用来表示一种“权重”,
//本例中,我们将key所占的字节数,作为weight。
//当cache中所有的“weight”总和达到maxKeyWeight时,将会触发“剔除策略”。
	cacheBuilder.maximumWeight(maxKeysWeight)
			.weigher(new Weigher<String, Object>() {
				@Override
				public int weigh(String key, Object value) {
					//粗略估计,不适用key.getBytes,避免一次不必要的解析与copy
					return key.length();
				}
			});
}

 

    需要注意,在Guava Cache中,“maximumSize”和“maximumWeight”两种控制cache量的参数,是互斥的,即同时只能设置其中一个。

 

    如果cache中不存在Key,那么意味着这个key的数据需要从一个可靠的地方load,我们有2中方式:

1、通过CacheLoader:

LoadingCache cache = cacheBuilder.build(new CacheLoader<String, Object>() {
                    //如果loader中返回null,则使用NULL占位符替代。
                    public Object load(String key) throws Exception {
                        if(valueLoader == null) {
                            return NULL;
                        }
                        Object value = valueLoader.get(key);
                        if(value == null) {
                            value = NULL;
                        }
                        return value;
                    }
                });

 

    其中valueLoader,是一个自定义的加载器,我们假定valueLoader.get方法,是通过redis从远端获取新的数据。CacheLoader的适应场景就是:当Guava Cache中没有key时,将会通过其load方法加载数据,并保存在Cache中。load方法不能返回NULL。

 

2、通过Callable:

    1)中,LoadingCache这个类通过和CacheLoader配合,完成Key的延迟加载。当然如果你不想使用CacheLoader这种统筹的方式,可以使用Callable接口, 那么你可以在需要的地方,使用Callable来自定义load操作。

Cache<String,Object> cache = cacheBuilder.build();
cache.get("user_id_10000", new Callable<Object>() {
	@Override
	public Object call() throws Exception {
		return redisClient.get("user_id_10000");
	}
});

 

    跟CacheLoader一样,callable.call方法返回的数据也会保存在Cache中。

 

Cache中数据“剔除”(Eviction)

    用户对cache的盲目使用,可能导致cache中数据不断增大,一个残酷的现实就是RAM资源非常有限,所以我们需要将那些不常用的数据移除,Guava cache基于LRU策略剔除数据,开发者只需要控制剔除数据的时机即可。

 

1、Size-based

    通过上述例子,我们已经知道可以通过CacheBuilder.maximumSize(long)方法指定cache中允许的key的个数。如果key的个数即将超过阀值(边际),将会根据LRU算法,剔除那些不常用的K-V。

 

    此外,如果你的每个Key-Value有不同的“weights”--比如每个K-V占用不同的内存量,我们可以用“weight”来描述这一指标。通过使用CacheBuilder.maximumWeights(long)和CacheBuilder.weigher(Weigher)来达成这一目的,当cache中put一个key时,都会计算它的weight值,并累加,当达到maximumWeight阀值时,会触发剔除操作。

 

2、Timed Eviction

    CacheBuilder提供了2中基于“时间”的剔除方式:

  • expireAfterAccess(long,TimeUnit):当key在被“read/write”操作之后,空闲多久后被删除。
  • expireAfterWrite(long,TimeUnit):当key被write(put或者reload)操作之后,空闲多久后被删除。

3、Reference-based

    JAVA中,一个对象的引用类型分为“强、弱、软”(还有“虚引用”),Guava Cache中也可以根据Key或者Value的引用类型,并结合GC,来完成cache数据的剔除。

  • CacheBuilder.weakKeys():将key存为WeakReference,如果JVM中,此key没有任何被任何“强引用”、“软引用”对象引用它,那么此K-V将会从cache中移除。
  • CacheBuilder.weakValues():同上。
  • CacheBuilder.softValues():同上。

“显性”移除

  • Cache.invalidate(key)
  • Cache.invalidateAll(keys)
  • Cache.invalidateAll():移除所有的数据

    CacheBuilder不会在数据过期时立即执行cleanup,这种数据剔除操作,通常是延迟的,在边际条件时,某些write或者read操作会触发cleanup。如果想更加及时的清理过期数据,那么需要自己去创建一个thread,然后周期性的执行cache.cleanUp()。Guava Cache并没有这么做,它主要考虑到,这种“cleanup”会和用户的正常操作产生“锁冲突”,对性能会有额外的干扰。如果开发者能够预料这种事情,那么你就可以这么做。

    

 

 

 

分享到:
评论

相关推荐

    spring-cache-demo:spring整合guava和redis实现本地和远程缓存

    在IT行业中,Spring框架是Java开发中的核心工具之一,它为构建高质量的、可维护的、松耦合的应用程序提供了全面的支持。...这个项目对于理解和实践Spring缓存、Guava Cache以及Redis的集成有着重要的参考价值。

    guava-21.0-rc2 、guava-21.0-rc2-javadoc 、guava-21.0-rc2-sources

    Guava是Google开发的一个核心库,它包含许多Java开发中常用和实用的工具类,极大地提高了开发效率。这里提到的"guava-21.0-rc2...通过了解并熟练使用Guava,开发者可以显著提高工作效率,同时也能遵循更好的编程实践。

    guava(google的java集合包)

    Guava是Google为Java平台...Guava的这些特性使其成为许多Java项目中的首选库,它不仅丰富了Java的工具箱,还提供了很多现代编程的最佳实践。在实际开发中,合理利用Guava可以提高代码质量,减少错误,并提升应用性能。

    guavapdf-ch_GoogleGuava官方教程_

    **Google Guava官方教程概述** Google Guava 是一个开源库,为Java开发人员...通过深入学习和实践Guava库,Java开发者可以提高代码质量和性能,充分利用Guava提供的各种工具和功能,让编程工作变得更加高效和便捷。

    guava源码src

    《深入解析Guava源码:探索Java编程的高级实践》 Guava,源自Google的开源Java库,以其丰富的集合框架、缓存机制、并发库、字符串处理工具等特性,成为了许多开发者在Java项目中的首选库。本文将围绕“guava源码src...

    Getting Started with Google Guava code

    **实践与学习路径** 为了更好地掌握 Guava,你可以: 1. 从官方文档开始,了解每个模块的功能和使用方法。 2. 阅读和分析示例代码,理解 Guava 工具类的用法。 3. 在实际项目中逐步引入 Guava 功能,替换传统代码...

    google-guava-18.0

    谷歌的Guava库是Java开发中的一个强大工具集,它为开发者提供了许多实用的功能,...对于开发者来说,理解和掌握Guava能有效提升Java应用的质量和效率,同时,通过阅读源码,还能深入了解设计模式和Java编程的最佳实践。

    guava-tests-17.0.zip

    【标题】:Guava Tests 17.0与开源文件缓存项目FileCache 【描述】:Guava Tests 17.0是一个Google维护的Java库,它包含了大量的测试用例,用于验证Guava库的各种功能。Guava是Google的一个核心库,提供了许多Java...

    Guava for java 实例学习

    Guava是Google开发的一款开源Java库,旨在促进最佳编码实践并减少编程错误。它提供了大量对集合、缓存、原始类型支持、并发、通用注解、字符串处理、I/O以及验证等方面的实用方法。Guava教程的目标是用简单直观的...

    Getting Started with Google Guava

    通过阅读《Getting Started with Google Guava》和实践书中提供的代码示例,读者可以深入了解如何在实际项目中有效利用Guava库,提升代码质量和效率。同时,`Getting Started with Google Guava_code.zip`文件包含了...

    guava相关资源

    通过查看源码,开发者可以深入理解Guava内部的工作机制,学习Google的编程实践,并且在遇到问题时能够更方便地调试和优化代码。 3. **Guava-19.0-javadoc.jar**: 这是Guava库的API文档,包含了所有公开类和方法的...

    Getting Started with Google Guava英文版

    #### 五、Google Guava最佳实践 1. **尽量使用不可变集合**:使用`ImmutableList`、`ImmutableSet`等不可变集合,可以有效避免集合被意外修改的问题。 2. **合理利用缓存机制**:根据实际情况选择合适的缓存策略,...

    Guava是个风火轮之基础工具(3)Java开发Java经

    《Guava是个风火轮之基础工具(3)Java开发Java经》这篇文档,作为Java开发者的重要参考资料,深入探讨了Google Guava库的基础工具在Java开发中的应用与实践。Guava是一个广泛使用的开源库,提供了许多高效且实用的...

    guava-learn:guava 学习代码库,和对 guava 源码的学习

    通过深入学习Guava,开发者不仅能掌握更多的编程技巧,还能了解到一些设计模式和最佳实践,这对于任何Java开发者来说都是一笔宝贵的财富。在实际项目中,合理运用Guava可以显著地改善代码的可读性和性能,使得软件...

    GuavaGoogle的Java核心库

    Guava是Google为Java开发者提供的一套强大的核心库,它极大地丰富了Java的标准库功能,尤其是在集合、缓存、并发编程、基本类型支持、注解处理、字符串操作以及输入/输出(I/O)等方面。Guava的目标是提高Java开发者的...

    java基础 集合-26-Guava开源组件使用(4)

    3. **Cache缓存**:Guava提供了强一致性的LoadingCache,这是一个可以自动加载数据的缓存系统。当尝试获取缓存中不存在的键时,可以通过提供的Loader自动计算或从其他数据源加载数据。这在处理昂贵的计算或数据库...

    Java Concurrency In Practice Learning Note

    总的来说,结合《Java并发编程实践学习笔记》和这些Guava相关的文档,开发者可以系统地学习Java并发编程,掌握如何在实际项目中运用并发技术,提高代码的并发性和效率,同时了解Google内部的并发缓存策略,提升大型...

    java缓存类

    在Java中,有许多库和框架提供了缓存功能,如Ehcache、Guava Cache以及Spring框架中的Cache Abstraction。本文将重点讨论Java缓存的基本概念、常用库及其工作原理。 首先,理解缓存的基本概念是非常重要的。缓存是...

    java实现cache小实例

    在Java编程中,缓存(Cache)是一种常用的技术,用于提高数据访问的速度。它通过存储最近或频繁访问的数据,使得再次请求时能快速获取,从而减少了对底层数据源的访问次数,提升了系统的性能。本实例将展示如何使用...

    guava-demo:多个方便的番石榴功能演示

    Guava 的 `LoadingCache` 类允许我们创建一个自动加载数据的缓存。它可以按照预设的策略(如定时过期、容量限制等)自动清除旧数据,提高性能并降低系统资源消耗。 3. **函数式编程** Guava 支持函数式编程风格,...

Global site tag (gtag.js) - Google Analytics