前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >guava缓存批量获取的一个坑

guava缓存批量获取的一个坑

作者头像
方丈的寺院
修改于 2019-10-17 10:00:12
修改于 2019-10-17 10:00:12
1.3K00
代码可运行
举报
文章被收录于专栏:方丈的寺院方丈的寺院
运行总次数:0
代码可运行

摘要

Guava Cache是Google开源的Java工具集库Guava里的一款缓存工具,一直觉得使用起来比较简单,没想到这次居然还踩了一个坑。

背景

功能需求抽象出来很简单,就是将数据库的查询 sthMapper.findById(Longid)的结果缓存起来。但同时还有批量请求,为了提高效率,肯定要批量查询数据库, sthMapper.findByIds(Collection<Long>ids)

对于的guava cache 处理类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 // 定义guava缓存
 public SthCache() {
        sthCache = CacheBuilder.newBuilder()
 .maximumSize(SIZE)
 .refreshAfterWrite(3, TimeUnit.SECONDS)
 .build(new CacheLoader<Long, List<Long>>() {
 @Override
 public List<Long> load(final Long id) {
 return doLoad(Arrays.asList(id)).get(id);
 }
 @Override
 public Map<Long, List<Long>> loadAll(
 final Iterable<? extends Long> ids)
 throws Exception {
 return doLoad(Lists.newArrayList(ids));
 }
 });
 }
// 实际从数据库中加载数据
private Map<Long, List<Long>> doLoad(final List<Long> ids) {
 return sthMapper.findByIds(ids);
} 
// 批量获取数据
 public Map<Long, List<Long>> getSthById(final List<Long> ids) {
 return sthCache.getAll(ids);
 }

问题

在debug的时候发现确实走的loadAll,批量查询数据库。但是上线后,线上监控数据却发现这个接口耗时很长,通过分析,发现有很多sthMappper.findByIds()的单个id查询。也就是说,并没有调用 loadAll,走到批量查询数据库中。

分析解决

  1. 首先看了下guava的代码实现 ImmutableMap<K,V>getAll(Iterable<?extendsK>keys)throwsExecutionException{inthits=0;intmisses=0;// 省略一大坨 try { if (!keysToLoad.isEmpty()) { try { // 调用loadAll Map<K, V> newEntries = loadAll(keysToLoad, defaultLoader);

批量查询时,对于没有命中的,确实调用的loadAll来加载数据的。

那问题就不是这边了。在 load()方法打了个断点,原因就找到了。

原来是refesh的时候加载的。refreshAfterWrite 刷新缓存数据时调用的还是load方法。

搜索了下,https://github.com/google/guava/issues/1975 github上这个issue还在。汗!!!

最后我这边解决是用 SpringCache统一了缓存管理。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方丈的寺院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入解析 Guava Cache- 从基本用法、回收策略、刷新策略到实现原理
Guava Cache 是非常强大的本地缓存工具,提供了非常简单 API 供开发者使用。
勇哥java实战
2025/05/16
1400
深入解析 Guava Cache- 从基本用法、回收策略、刷新策略到实现原理
Spring Boot 集成 本地缓存Guava框架
本地缓存一般位于应用服务器的部署机器上,使用应用服务器本身的少量内存。它是应用层获取数据的第一道缓存,应用层获取数据时先访问本地缓存,如果未命中,再通过远程从 L1 缓存层获取,最终获取到的数据再预热到本地缓存中。
微观技术
2021/04/19
1.5K0
Spring Boot 集成 本地缓存Guava框架
Google Guava Cache 使用
缓存在很多场景下都是相当有用的。例如,计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。
MickyInvQ
2020/09/27
1.3K0
3. java缓存-线程内缓存guava cache
根据上图中的缓存框架,我们常用的一些缓存实例有:LocalManualCache和LocalLoadingCache,两者唯一的区别就是LocalLoadingCache extends LocalManualCache implements LoadingCache<K,V>接口。 LocalManualCache和LocalLoadingCache两者都是对LoaclCache的包装,而LocalCache就是一个缓存的存储器,通过继承AbstractMap和实现ConcurrentMap接口,实现了支持并发的本地map(可以看成类似的ConcunrrentHashMap),LocalCache不对外暴露,因此只能通过其他方式提供实例,这就是CacheBuilder,以后建议大家也可以通过Builder的形式对外暴露实例。
全栈程序员站长
2022/11/09
9050
3. java缓存-线程内缓存guava cache
使用 Guava 实现简洁高效的本地缓存
在现代应用中,缓存是提升性能和降低外部系统压力的关键组件。Google 提供的 Guava 是一款强大的 Java 工具库,其中的 Guava Cache 模块提供了灵活的本地缓存功能。
用户1142828
2024/11/30
1320
Guava Cache用法介绍(极简版)
看了官方的关于Guava Cache的介绍,感觉太过于啰嗦,我个人是很不喜欢,看了好大半天也看不懂,直到翻到了一篇国内的文章才看懂,特此记录,以备查阅。
诺浅
2020/08/20
4.6K0
Guava -- 集合类 和 Guava Cache
Guava 是 google 推出的一个第三方 java 库,用来代替 jdk 的一些公共操作,给我印象特别深的就是 Collection 的扩展和本地缓存的扩展这两个方面了。所以今天也就主要来讲讲 guava 的 collection 和 caches 两方面。
希希里之海
2019/08/20
1.2K0
GuavaCache学习笔记三:底层源码阅读
申明:转载自 https://www.cnblogs.com/dennyzhangdd/p/8981982.html
一枝花算不算浪漫
2018/12/25
1.1K0
重新认识下JVM级别的本地缓存框架Guava Cache(3)——探寻实现细节与核心机制
通过《重新认识下JVM级别的本地缓存框架Guava Cache——优秀从何而来》一文,我们知道了Guava Cache作为JVM级别的本地缓存组件的诸多暖心特性,也一步步地学习了在项目中集成并使用Guava Cache进行缓存相关操作。Guava Cache作为一款优秀的本地缓存组件,其内部很多实现机制与设计策略,同样值得开发人员深入的掌握与借鉴。
是Vzn呀
2022/11/30
9600
Guava Cache最佳实践
使用缓存一定要防止缓存占用过多的内存,导致程序OOM。需要对缓存的内存使用量进行限制,同时还需要设置过期或刷新策略。
十毛
2019/03/27
1.9K0
读源码——Guava-Cache
今天,听同事介绍了Cuava-cache,这是个老牌缓存了,虽然近来被Caffine的出现遮盖了风头,但依然不能掩盖它往日的辉煌,至少在我们团队,还有很多项目在使用它,索性就以它为基础,对缓存做一次总结。
早安嵩骏
2020/08/11
8870
本地缓存组件 Guava cache 详解
缓存分为本地缓存和远端缓存。常见的远端缓存有Redis,MongoDB;本地缓存一般使用map的方式保存在本地内存中。一般我们在业务中操作缓存,都会操作缓存和数据源两部分。如:put数据时,先插入DB,再删除原来的缓存;ge数据时,先查缓存,命中则返回,没有命中时,需要查询DB,再把查询结果放入缓存中 。如果访问量大,我们还得兼顾本地缓存的线程安全问题。必要的时候也要考虑缓存的回收策略。
BUG弄潮儿
2021/10/08
2.7K1
本地缓存组件 Guava cache 详解
[Google Guava]-缓存详解
缓存在很多场景下都是相当有用的。例如,计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。 Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地, Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也是很有用的,因为它会自动加载缓存。 LoadingCache是附带CacheLoader构建而成的缓存实现。创建自己的CacheLoader通常只需要简单地实现V load(K key) throws Exception方法。
用户5166556
2019/04/16
1K0
Redis+Caffeine构建高性能二级缓存
在现代分布式系统设计中,缓存是优化服务性能的核心组件。标准实现方案采用远程缓存(如Redis/Memcached)作为数据库前置层,通过以下机制提升性能:
摘星.
2025/05/20
1080
Redis+Caffeine构建高性能二级缓存
Caffeine Cache 进程缓存之王
互联网软件神速发展,用户的体验度是判断一个软件好坏的重要原因,所以缓存就是必不可少的一个神器。在多线程高并发场景中往往是离不开cache的,需要根据不同的应用场景来需要选择不同的cache,比如分布式缓存如redis、memcached,还有本地(进程内)缓存如ehcache、GuavaCache、Caffeine。
Bug开发工程师
2019/07/13
4.1K0
还在用Guava Cache?它才是Java本地缓存之王
提到本地缓存,大家都能想到Guava Cache,他的优点是封装了get,put操作;提供线程安全的缓存操作;提供过期策略;提供回收策略;缓存监控。当缓存的数据超过最大值时,使用LRU算法替换。这一篇我们将要谈到一个新的本地缓存框架:Caffeine Cache。它也是站在巨人的肩膀上-Guava Cache,借着他的思想优化了算法发展而来。
用户1516716
2020/09/14
1.5K0
还在用Guava Cache?它才是Java本地缓存之王
Java内存缓存-通过Google Guava创建缓存
Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中。实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问。
小码农薛尧
2019/08/27
2.9K0
Java内存缓存-通过Google Guava创建缓存
Java本地内存LoadingCache介绍
最简单的设计就是一个大的HashMap,这样在多线程写的时候会有问题,当然也可以用并发场景下高性能的ConcurrencyHashMap;当然还可以自己设计底层的存储结构;
心平气和
2022/03/29
2.3K0
Java本地内存LoadingCache介绍
本地缓存无冕之王Caffeine Cache
在常规的软件开发流程中,缓存的重要性日益凸显。它不仅为用户带来了更迅速的反馈时间,还能在大多数情况下有效减轻系统负荷。
BookSea
2023/09/19
6940
本地缓存无冕之王Caffeine Cache
GuavaCache 简单入门
缓存在各种用例中非常有用。尤其是当计算或者检索的代价很高,而需要多次在输入上检索这个值得时候,应该使用缓存。
2019/01/28
1.8K0
相关推荐
深入解析 Guava Cache- 从基本用法、回收策略、刷新策略到实现原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档