Guava Cache 异步刷新技巧,你值得拥有!

以下文章来源于勇哥Java实战 ,作者勇哥

Guava Cache是一款非常优秀的本地缓存框架。

这篇文章,我们聊聊如何使用 Guava Cache 异步刷新技巧带飞系统性能 。

图片

1 经典配置

Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似,提供了基于时间、容量、引用三种回收策略,以及自动加载、访问统计等功能。

图片

首先,我们温习下 Gauva Cache 的经典配置 。

图片

例子中,缓存最大容量设置为 100 (基于容量进行回收),配置了失效策略刷新策略

1、失效策略

配置 expireAfterWrite 后,缓存项在被创建或最后一次更新后的指定时间内会过期。

2、刷新策略

配置 refreshAfterWrite 设置刷新时间,当缓存项过期的同时可以重新加载新值 。

这个例子里,有的同学可能会有疑问:为什么需要配置刷新策略,只配置失效策略不就可以吗

当然是可以的,但在高并发场景下,配置刷新策略会有奇效,接下来,我们会写一个测试用例,方便大家理解 Gauva Cache 的线程模型。

2  理解线程模型

我们模拟在多线程场景下,「缓存过期执行 load 方法」和「刷新执行 reload 方法」两者的运行情况。

图片

执行结果见下图:

图片

执行结果表明:Guava Cache 并没有后台任务线程异步的执行 load 或者 reload 方法。

  1. 失效策略expireAfterWrite 允许一个线程执行 load 方法,其他线程阻塞等待 。

    当大量线程用相同的 key 获取缓存值时,只会有一个线程进入 load 方法,而其他线程则等待,直到缓存值被生成。这样也就避免了缓存击穿的危险。高并发场景下 ,这样还是会阻塞大量线程。

  2. 刷新策略refreshAfterWrite 允许一个线程执行 load 方法,其他线程返回旧的值。

    单个 key 并发下,使用 refreshAfterWrite ,虽然不会阻塞了,但是如果恰巧同时多个 key 同时过期,还是会给数据库造成压力。

为了提升系统性能,我们可以从如下两个方面来优化 :

  1. 配置  refresh < expire ,减少大量线程阻塞的概率;

  2. 采用异步刷新的策略,也就是线程异步加载数据,期间所有请求返回旧的缓存值,防止缓存雪崩。

下图展示优化方案的时间轴 :

图片

3 两种方式实现异步刷新

3.1 重写 reload 方法

图片

3.2 实现 asyncReloading 方法

图片

不管使用哪种方案, 都需要定义单独的线程池来执行刷新任务 。

4 异步刷新 + 多级缓存

2018 年,笔者服务的一家电商公司需要进行 app 首页接口的性能优化。笔者花了大概两天的时间完成了整个方案,采取的是两级缓存模式,同时采用了 Guava 的异步刷新机制。

整体架构如下图所示:

图片

缓存读取流程如下 :

1、业务网关刚启动时,本地缓存没有数据,读取 Redis 缓存,如果 Redis 缓存也没数据,则通过 RPC 调用导购服务读取数据,然后再将数据写入本地缓存和 Redis 中;若 Redis 缓存不为空,则将缓存数据写入本地缓存中。

2、由于步骤 1 已经对本地缓存预热,后续请求直接读取本地缓存,返回给用户端。

3、Guava 配置了 refresh 机制,每隔一段时间会调用自定义 LoadingCache 线程池(5个最大线程,5个核心线程)去导购服务同步数据到本地缓存和 Redis 中。

优化后,性能表现很好,平均耗时在 5ms 左右,同时大幅度的减少应用 GC 的频率。

该方案依然有瑕疵,一天晚上我们发现 app 端首页显示的数据时而相同,时而不同。

也就是说:虽然 LoadingCache 线程一直在调用接口更新缓存信息,但是各个服务器本地缓存中的数据并非完成一致。

这说明了两个很重要的点:

1、惰性加载仍然可能造成多台机器的数据不一致;

2、LoadingCache 线程池数量配置的不太合理,  导致了任务堆积。

最终,我们的解决方案是:

1、异步刷新结合消息机制来更新缓存数据,也就是:当导购服务的配置发生变化时,通知业务网关重新拉取数据,更新缓存。

2、适当调大 LoadingCache 的线程池参数,并在线程池埋点,监控线程池的使用情况,当线程繁忙时能发出告警,然后动态修改线程池参数。

5 总结

Guava Cache 非常强大,它并没有后台任务线程异步的执行 load 或者 reload 方法,而是通过请求线程来执行相关操作。

为了提升系统性能,我们可以从如下两个方面来处理 :

  1. 配置 refresh < expire,减少大量线程阻塞的概率。

  2. 采用异步刷新的策略,也就是线程异步加载数据,期间所有请求返回旧的缓存值

笔者曾经优化过某电商网站的首页接口,使用的方案是:Guava 的异步刷新机制 + 多级缓存 ,取得了非常好的优化效果。

尽管如此,我们在使用这种方式时,依然需要考虑的缓存和数据库一致性问题。


参考资料:

https://albenw.github.io/posts/df42dc84/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/599506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

citeSpace保姆级安装使用教程

citeSpace保姆级安装使用教程 文章目录 citeSpace保姆级安装使用教程CiteSpace功能与参数区安装使用知网数据导出citespace数据导入结果 设置操作隐藏节点 CiteSpace功能与参数区 安装 citeSpace安装教程 citespace下载 网址&#xff1a;https://citespace.podia.com/ 安装之…

STM32使用中断方式进行USART数据收发以及printf函数的重写

时间记录&#xff1a;2024/1/5 一、USART/UART介绍 协议介绍 &#xff08;1&#xff09;起始位&#xff0c;一位逻辑电平0表示 &#xff08;2&#xff09;数据位&#xff0c;8-9位&#xff0c;逻辑高低电平&#xff0c;一般使用8位 &#xff08;3&#xff09;校验位&#xff…

2-sql注入之sqli-labs靶场搭建

文章目录 SQL注入之sqli-labs靶场搭建1、Sqli-labs环境安装需要安装以下环境工具下载链接&#xff1a; 2、phpstudy连接mysql总是启动了又停止第一种情况可能是端口占用问题第二种情况就是曾经在电脑上安装过mysql SQL注入之sqli-labs靶场搭建 Sqli-labs是一个印度程序员写的&…

vmware中ubuntu虚拟机不能够用共享文件夹

有时候发现装好虚拟机后&#xff0c;然后 虚拟机-设置-选项-共享文件夹 然后使用快捷键ctrlaltt 打开命令行&#xff0c;cd /mnt下没有看到hgfs文件夹 解决办法是安装vmware tools工具 此时想通过点击 虚拟机-安装vmwaretools工具 按钮 居然发现该按钮是灰色的&#xff0…

CMake入门教程【核心篇】动态库(dll, so)

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 CMake入门教程【核心篇】动态库(dll, so)1.简介2.动态库的优势3.动态库的劣势4.创建动态库5.完整代码示例6.实战使用技巧与注意事项

实现文件拖拽上传的功能

1 先来看一下效果 2 我们来看一下代码执行的结果&#xff1a; 我们创建目标的容器盒子 和可以展示数据的ul 监听进入目前盒子的事件 3 文件进入目标容器中解析文件

Python中 的函数介绍

函数 在Python中,函数是用来执行某种功能的 函数定义 def function_name(参数列表):代码块[return val]比如 #---------------定义------------- def add_3(num):newnum num3return newnumnum 3 print(add_3(num))函数调用 def add_3(num):newnum num3return newnumnum …

科研上新 | 第6期:优化LLM数学推理;深度学习建模基因表达调控;基于深度学习的近实时海洋碳汇估算

编者按&#xff1a;欢迎阅读“科研上新”栏目&#xff01;“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里&#xff0c;你可以快速浏览研究院的亮点资讯&#xff0c;保持对前沿领域的敏锐嗅觉&#xff0c;同时也能找到先进实用的开源工具。 本期内容速览 …

在 IDEA 中创建JavaWeb 项目的方式(超详细步骤教程和遇到的问题)

目录 0-1项目图片操作步骤链接0-2项目结构预览1.新建Project2.定义项目名称3.创建完成后项目结构4.创建config文件夹4.1 作用 5.在WEB-INF下创建lib文件夹5.1然后搞几个常用的jar包放入5.1.1jar包全选中后右键选择放入类库5.1.2jar包全选中后右键选择放入类库 6.创建src下文件夹…

软件测试金融项目经验总结,面试题都问什么?

1、APP端/客户端接口加解密介绍 加密方式&#xff08;两种&#xff09;&#xff1a; 在TCP/IP四层模型中的应用层进行加密。类似密码本&#xff0c;当前项目使用的是这种&#xff0c;可以看到所有响应内容&#xff0c;只是看不懂。 在TCP/IP四层模型中的运输层和应用层之间进行…

「Vue3面试系列」Vue3 所采用的 Composition Api 与 Vue2 使用的 Options Api 有什么不同?

文章目录 开始之前正文一、Options Api二、Composition Api三、对比逻辑组织Options APICompostion API 逻辑复用 小结 开始之前 Composition API 可以说是Vue3的最大特点&#xff0c;那么为什么要推出Composition Api&#xff0c;解决了什么问题&#xff1f; 通常使用Vue2开…

网工内推 | 保险业网工,有绩效奖金,CISP认证优先,最高16K

01 华贵人寿保险股份有限公司 招聘岗位&#xff1a;系统管理岗&#xff08;主机管理方向&#xff09; 职责描述&#xff1a; 1.负责数据中心私有云平台的规划建设以及后期的运行维护&#xff1b; 2.负责公司操作系统的规划、部署与日常维护&#xff1b; 3.负责操作系统运维相关…

rime中州韵小狼毫 help lua Translator 帮助消息翻译器

lua 是 Rime中州韵/小狼毫输入法强大的武器&#xff0c;掌握如何在Rime中州韵/小狼毫中使用lua&#xff0c;你将体验到什么叫 随心所欲。 先看效果 在 rime中州韵 输入效果一览 中的 &#x1f447; help效果 一节中&#xff0c; 我们看到了在Rime中州韵/小狼毫输入法中输入 h…

算法第十一天-组合总和Ⅳ

组合总和Ⅳ 题目要求 解题思路 来自[负雪明烛] 题目有个明显的提示&#xff1a;求组合的个数&#xff0c;而不是每个组合。如果是要求出每个组合&#xff0c;那么必须使用回溯法&#xff0c;保存所有路径。但是如果是组合个数&#xff0c;一般都应该想到[动态规划]的解法。 直…

记录 搭载小车 运行激光slam lio-sam fast-lio2

用了将近一个月搭载了一台履带车 其中 主控&#xff1a;NUC i7-8559U 激光雷达为&#xff1a;velodyne16线和hesai64线 IMU为&#xff1a;轮趣N100 mini 对imu使用上位机进行调平矫正 设置输出400HZ 对外参标定 首先使用velodyne16线 安装驱动直接运行&#xff0c;没遇到啥…

人工智能_机器学习092_使用三维瑞士卷数据_利用分层聚类算法进行瑞士卷数据三维聚类---人工智能工作笔记0132

然后我们使用分层聚类算法来对我们导入的瑞士卷数据进行聚类 agg =AgglomerativeClustering(n_clusters = 6,linkage = ward) 可以看到这里我们使用的,聚类距离计算用的是,ward这种,最小化簇内方差的形式,l进行聚类对吧 可以看到这个linkage参数有好几个选择对吧,是之前我们讲过…

网络通信理论-入门1

网口框架 100M 2. 物理层解读 2.1 同步的方法&#xff1a;编码 为了让接收方在没有外部时钟参考的情况也能确定每一位的起始、结束和中间位置&#xff0c;在传输信号时不直接采用二进制编码。在 10BASE-T 的传输方式中采用曼彻斯特编码&#xff0c;在 100BASE-T 中则采用 4B/…

Java JDBC整合(概述,搭建,PreparedStatement和Statement,结果集处理)

一、JDBC的概述&#xff1a; JDBC&#xff1a;是一种执行sql语句的Java APL&#xff0c;可以为多种关系类型数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。有了JDBC&#xff0c;Java人员只需要编写一次程序就可以访问不同的数据库。 JDBC APL&#xf…

Python+PyCharm的安装配置及教程(实用)

python and PyCharm 安装教程可参考&#xff1a;https://blog.csdn.net/wangyuxiang946/article/details/130634049 Pyhon 下载地址&#xff1a;https://www.python.org/downloads/ PyCharm 下载地址&#xff1a;https://www.jetbrains.com/pycharm/download/?sectionwindo…

AP9196 DC-DC升压恒流电源管理芯 3-40V 200W升降压线路图

产品说明 AP9196 是一系列电路简洁的宽调光比升压调光恒流驱动器&#xff0c;适用于 3-40V 输入电压范围的 LED照明领域。AP9196 采用我司专利算法&#xff0c;可以实现高精度的恒流效果&#xff0c;输出电流恒流精度≤3&#xff05;&#xff0c;电压工作范围为5-40V&#xff0…