浅析本地缓存技术-Guava Cache | 京东物流技术团队

京东云开发者
• 阅读 340

1 引言

作为java开发工作者,相信大家对于guava这个工具包都不会太陌生,而对于本地缓存技术guava cache,大家在日常的工作开发中也都有所了解,接下来本文就从各个角度入手来对于Google提供的guava cache进行解析。

2 guava cache应用场景

本地缓存的数据读写都在一个进程内,相对与redis等分布式缓存,不需要网络传输的过程,访问速度很快,同时也受到JVM内存的制约,无法在数据量较多的场景下使用。

基于以上特点,guava cache的主要应用场景为以下几种:

  • 对于访问速度有较大要求
  • 存储的数据不经常变化
  • 数据量不大,占用内存较小
  • 需要访问整个集合
  • 能够容忍数据不是实时的

在这里guava cache被用于储存参数配置,也符合以上的应用场景条件。

浅析本地缓存技术-Guava Cache | 京东物流技术团队

3 guava cache的使用方式

guava cache位于com.google.common.cache包下,核心的类有两个,一个是CacheBuilder,是用来构建缓存的,另一个是Cache,也就是缓存容器,用来存放缓存数据的。

要使用guava cache,首先要引入maven依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>

接下来写一个简单的示例:

Cache<String, String> localCache = CacheBuilder.newBuilder()
                .initialCapacity(5)
                .maximumSize(10)
                .concurrencyLevel(3)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build();

以上示例实例化了一个本地缓存,接下来介绍一下初始化的各项参数的含义:
initialCapacity:内部哈希表的最小容量,也就是cache的初始容量。

maximumSize:cache的最大缓存数。

concurrencyLevel:并发等级,也可以定义为同时操作缓存的线程数,由

浅析本地缓存技术-Guava Cache | 京东物流技术团队

可以看出,这个线程数默认为4。

expireAfterWrite:缓存写入后刷新时间。

从缓存中获取数据调用的方法为get(K key, Callable<? extends V> loader)方法,此方法的含义是根据键key获取数据,若key不存在,则通过执行指定的Callable方法来构造缓存,示例代码如下所示:

Map<String, Dicdetail> dicDetailMap = ObLocateCache.locateConfigCache.get(key.toString(), new Callable<Map<String, Dicdetail>>() {
                @Override
                public Map<String, Dicdetail> call() throws Exception {
                    return getConfigParameterFromMaster(baseDomain, KeyConstants.WMS5_LOCATE_MANUAL);
                }
            });

从cache中删除数据分为被动删除和主动删除两种:

1.被动删除:

  • 基于数据大小删除:LRU+FIFO
  • 基于过期时间删除:在指定时间内没有被访问
  • 基于引用删除:通过weakKeys和weakValues方法指定Cache只保存对缓存记录key和value的弱引用。这样当没有其他强引用指向key和value时,key和value对象就会被垃圾回收器回收

2.主动删除:

//删除指定的key对应数据
cache.invalidate("s");
//将一批对应的数据删除
cache.invalidateAll(Arrays.asList("st","r","ing"));
//全部删除
cache.invalidateAll();

4 根据源码分析guava cache的存储原理

guava cache的数据结构跟ConcurrentHashMap类似,二者最基本的区别是ConcurrentMap会一直保存所有添加的元素,直至将添加的元素移除。相对地,guava cache为了限制内存占用,通常都设定为自动回收元素。

guava cache的核心类为LocalCache,LocalCache实现了ConcurrentMap接口。其中有一个Segment数组,如下所示

浅析本地缓存技术-Guava Cache | 京东物流技术团队

获取数据的方法源码如下图所示,可以看出guava cache的存储原理为由Segment数组加上ReferenceEntry链表加上AtomicReferenceArray数组组成的数据结构。

浅析本地缓存技术-Guava Cache | 京东物流技术团队

浅析本地缓存技术-Guava Cache | 京东物流技术团队

浅析本地缓存技术-Guava Cache | 京东物流技术团队

数据结构图如下所示:

浅析本地缓存技术-Guava Cache | 京东物流技术团队

Segement数组的长度决定了cache的并发数。每一个Segment都继承了ReentrantLock,使用了单独的锁,对Segment的写操作需要先拿到锁。写操作部分源码如下所示:

浅析本地缓存技术-Guava Cache | 京东物流技术团队

浅析本地缓存技术-Guava Cache | 京东物流技术团队

5 总结

本文简要叙述了guava cache的应用场景以及简单的使用方式,通过源码对于guava cache的存储原理以及简单的读写方法进行了介绍。相信通过阅读本文,能够对于常见的guava cache有一个大致的认知。

作者:京东物流 王辰玮

来源:京东云开发者社区 自猿其说Tech

点赞
收藏
评论区
推荐文章
京东APP百亿级商品与车关系数据检索实践 | 京东云技术团队
本文主要讲解了京东百亿级商品车型适配数据存储结构设计以及怎样实现适配接口的高性能查询。通过京东百亿级数据缓存架构设计实践案例,简单剖析了jimdb的位图(bitmap)函数和lua脚本应用在高性能场景。希望通过本文,读者可以对缓存的内部结构知识有一定了解,并且能够以最小的内存使用代价将位图(bitmap)灵活应用到各个高性能实际场景。
Wesley13 Wesley13
3年前
Java本地缓存框架系列
Caffeine是一个基于Java8的高性能本地缓存框架,其结构和GuavaCache基本一样,api也一样,基本上很容易就能替换。Caffeine实际上就是在GuavaCache的基础上,利用了一些Java8的新特性,提高了某些场景下的性能效率。这一章节我们会从Caffeine的使用引入,并提出一些问题,之后分析其源代码解
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Redis 缓存性能实践及总结
一、前言在互联网应用中,缓存成为高并发架构的关键组件。这篇博客主要介绍缓存使用的典型场景、实操案例分析、Redis使用规范及常规Redis监控。二、常见缓存对比常见的缓存方案,有本地缓存,包括HashMap/ConcurrentHashMap、Ehcache、Memcache、GuavaCache等,缓存中间件包
Wesley13 Wesley13
3年前
MySQL数据库InnoDB存储引擎Log漫游(1)
作者:宋利兵来源:MySQL代码研究(mysqlcode)0、导读本文介绍了InnoDB引擎如何利用UndoLog和RedoLog来保证事务的原子性、持久性原理,以及InnoDB引擎实现UndoLog和RedoLog的基本思路。00–UndoLogUndoLog是为了实现事务的原子性,
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
京东云开发者 京东云开发者
10个月前
分布式日志追踪ID实战 | 京东物流技术团队
本文通过介绍分布式应用下各个场景的全局日志ID透传思路,以及介绍分布式日志追踪ID简单实现原理和实战效果,从而达到通过提高日志查询排查问题的效率。背景开发排查系统问题用得最多的手段就是查看系统日志,相信不少人都值过班当过小秘吧:给下接口和出入参吧,麻烦看看