Guava Cache 异步刷新技巧

前言

Guava Cache是一款非常优秀的本地缓存框架,提供简洁易用的 API 供开发者使用。

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

1 基本用法

首先,在 Java 应用中添加 maven 依赖:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version>
</dependency>

然后编写测试用例:

LoadingCache 是本地缓存工具,支持配置加载函数定时失效等功能。

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

  1. 定时失效

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

  1. 刷新函数

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

我们模拟过期执行 load 方法 / 重新加载执行 reload 方法的流程,执行结果见下图:

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

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

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

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

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

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

  1. 减少过期的频率 ,也就是减少执行 load 方法的频率 ,配置 refresh < expire 。
  2. 采用异步刷新的策略,也就是线程异步加载数据,期间所有请求返回旧的缓存值

2 两种方式实现异步刷新

2.1 重写 reload 方法

2.2 实现 asyncReloading 方法

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

3 异步刷新 + 多级缓存

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 的线程池参数,并在线程池埋点,监控线程池的使用情况,当线程繁忙时能发出告警,然后动态修改线程池参数。

4 总结

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

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

  1. 减少过期的频率 ,也就是减少执行 load 方法的频率 ,配置 refresh < expire 。
  2. 采用异步刷新的策略,也就是线程异步加载数据,期间所有请求返回旧的缓存值

联系方式

如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

同时可以通过关注公众号《编程乐学》进行留言,同时,公众号还有更多有趣的项目以及关于学习编程的笔记资料大家可以看看,欢迎大家进行留言。

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

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

相关文章

我发现了一个还行的生成图片的网站(新人登录可领30金币)

这个网站是一个生成图片的在线工具&#xff0c;它提供了多种功能和选项&#xff0c;让用户可以轻松地创建各种风格和类型的图片。它的界面简洁易用&#xff0c;新用户登录后还可以获得30个金币的奖励。这些金币可以用来解锁更多的高级功能和特效。用户可以选择不同的背景、字体…

彻底认识Unity ui设计中Space - Overlay、Screen Space - Camera和World Space三种模式

文章目录 简述Screen Space - Overlay优点缺点 Screen Space - Camera优点缺点 World Space优点缺点 简述 用Unity中开发了很久&#xff0c;但是对unity UI管理中Canvas组件的Render Mode有三种主要类型&#xff1a;Screen Space - Overlay、Screen Space - Camera和World Spa…

mysql-数据库DDL操作

之前已经学习了安装mysql服务端还有进行了一些关于数据库安全的设置&#xff0c;现在开始学习创建数据库和数据表以及进行修改。 MySQL的DDL&#xff08;Data Definition Language&#xff09;语句用于定义或更改数据库结构&#xff0c;包括创建、修改或删除表、视图、索引等数…

详细平稳解

1.详细平衡 定义&#xff1a;一个在高斯白噪声激励下的动力学系统在状态空间中如果用如下运动方程描述&#xff1a; d d t X j \frac{d}{dt}\mathbf{X}_{j} dtd​Xj​ f j ( X ) f_{j}(\mathbf{X}) fj​(X) ∑ l 1 m g j l ( X ) W l ( t ) \sum_{l1}^{m}g_{jl}(\mathbf{X})W…

Open CASCADE学习|入门Hello world

目录 1、新建项目 2、写代码 3、配置 3.1配置头文件 3.2配置静态库文件 3.3配置动态库文件 4、编译运行 1、新建项目 新建一个Win32控制台应用程序&#xff0c;取名为HelloWorld&#xff0c;如下图所示&#xff1a; 2、写代码 测试所用的代码如下&#xff1a; // Use T…

Redis:原理速成+项目实战——Redis实战6(封装缓存工具(高级写法)缓存总结)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战5&#xff08;互斥锁、逻辑过期解决缓存击穿问题&#xff09; &#x1f4da;订…

C# Entity Framework 中不同的数据的加载方式

延迟加载 延迟加载是指在访问导航属性时&#xff0c;Entity Framework 会自动查询数据库并加载相关数据。这种方式在我们需要访问导航属性时比较方便&#xff0c;因为我们无需手动加载相关数据&#xff0c;而且只会在需要时才会进行查询&#xff0c;从而减少了不必要的开销。但…

Python基础-07(for循环、range()函数)

文章目录 前言一、for循环1.for循环结构2.参数 end&#xff08;使其输出时变为横向&#xff09; 二、range()函数1.range(常数)2.range(起始值&#xff0c;结束值)3.range(起始值&#xff0c;结束值&#xff0c;步长)4.例子 总结 前言 此章介绍循环结构中最常用的循环&#xf…

Redisson与SQL乐观锁:实现接口幂等性的终极指南与实战演示

Redisson与SQL乐观锁&#xff1a;实现接口幂等性的终极指南与实战演示 Redisson与SQL乐观锁&#xff1a;实现接口幂等性的终极指南与实战演示 接口幂等性.md

497 蓝桥杯 成绩分析 简单

497 蓝桥杯 成绩分析 简单 //C风格解法1&#xff0c;*max_element&#xff08;&#xff09;与*min_element&#xff08;&#xff09;求最值 //时间复杂度O(n)&#xff0c;通过率100% #include <bits/stdc.h> using namespace std;using ll long long; const int N 1e4 …

java基于VUE3+SSM框架的在线宠物商城+vue论文

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

【langchain】在单个文档知识源的上下文中使用langchain对GPT4All运行查询

In the previous post, Running GPT4All On a Mac Using Python langchain in a Jupyter Notebook, 我发布了一个简单的演练&#xff0c;让GPT4All使用langchain在2015年年中的16GB Macbook Pro上本地运行。在这篇文章中&#xff0c;我将提供一个简单的食谱&#xff0c;展示我们…

【Docker基础三】Docker安装Redis

下载镜像 根据自己需要下载指定版本镜像&#xff0c;所有版本看这&#xff1a;Index of /releases/ (redis.io) 或 https://hub.docker.com/_/redis # 下载指定版本redis镜像 docker pull redis:7.2.0 # 查看镜像是否下载成功 docker images 创建挂载目录 # 宿主机上创建挂…

element-ui table height 属性导致界面卡死

问题: 项目上&#xff0c;有个点击按钮弹出抽屉的交互, 此时界面卡死 原因分析: 一些场景下(父组件使用动态单位/弹窗、抽屉中使用), element-ui 的 table 会循环计算高度值, 导致界面卡死 github 上的一些 issues 和解决方案: Issues ElemeFE/element GitHub 官方讲是升…

bootstrap教程

bootstrap教程 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同进入前端开发的世界&#xff0c;探索一款备受欢迎的前端框架——Bootstra…

修改安卓apk设置为安卓主屏幕(launcher)

修改安卓apk 将apk可以设置安卓主屏幕 原理&#xff1a; 将打包好的apk文件进行拆包增加配置文件在重新编译回apk包 需要得相关文件下载 解包 apktool :https://pan.baidu.com/s/1oyCIYak_MHDJCvDbHj_qEA?pwd5j2xdex2jar&#xff1a;https://pan.baidu.com/s/1Nc-0vppVd0G…

2024年学习计划

2024-2-29号完成 机器视觉基础知识学习&#xff0c;并可以处理视觉工作中的需求。 2024-3月份学习SCARA机械手应用开发SCARA机器人-埃斯顿自动化 - ESTUN 2024-4月份继续学习python 好了&#xff0c;今年可以完成这三个目标就满足了 好好学习&#xff0c;天天向上。每天进步…

【数据库系统概论】数据库并发控制机制——并发控制的主要技术之封锁(Locking)

系统文章目录 数据库的四个基本概念&#xff1a;数据、数据库、数据库管理系统和数据库系统 数据库系统的三级模式和二级映射 数据库系统外部的体系结构 数据模型 关系数据库中的关系操作 SQL是什么&#xff1f;它有什么特点&#xff1f; 数据定义之基本表的定义/创建、修改和…

Vue CLI组件通信

目录 一、组件通信简介1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 二、props1.Props 定义2.Props 作用3.特点4.代码演示 三、props校验1.思考2.作用3.语法4.代码演示 四、prop…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第四天-Linux管道练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…