缓存神器-JetCache

序言

今天和大家聊聊阿里的一款缓存神器 JetCache。

一、缓存在开发实践中的问题

1.1 缓存方案的可扩展性问题

谈及缓存,其实有许多方案可供选择。例如:Guava Cache、Caffine、Encache、Redis 等。

这些缓存技术都能满足我们的需求,但现在有一个问题是:技术是在不断发展的,若今后有更好的缓存技术出现,如果我们需要替换之前的缓存方案,该怎么办呢?

1.2 缓存的使用问题

之前,我们已经了解到缓存方案有许多,而这些缓存在项目中的使用方式又不尽相同。这无疑将增加我们的学习成本以及开发成本(即:开发人员需要了解并掌握所使用缓存技术的使用方式以及原理)。

现如今我们的项目大多都是分布式环境,在分布式环境中有三大经典的分布式缓存问题:

  1. 缓存穿透
  2. 缓存击穿
  3. 缓存雪崩

针对这些问题,具体的缓存技术似乎并不能解决。那么,这就意味着需要开发人员每次在使用缓存时,都需要手动解决这些问题。针对这些固定的问题,是否可以采用成熟、统一的方案解决呢?

二、JSR-107 规范

在开发过程中,我们经常会用到缓存来提高系统的性能和效率。然而,不同的缓存实现可能会有各自的接口和行为,这就导致了在切换缓存实现或者在不同的缓存实现之间共享数据时会遇到困难。

JSR-107,也被称为 JCache,是由 Java 定义的一项规范。JSR-107 规范定义了一套标准的 Java 缓存 API,使得开发者可以用一致的方式来使用和切换不同的缓存实现。这样,无论你使用哪种缓存技术,只要它们遵循 JSR-107 规范,你就可以用同样的方式来操作缓存。

三、JetCache 方案

JetCache 是阿里推出的一个基于 Java 的缓存系统封装,提供统一的 API 和注解来简化缓存的使用。 JetCache提供了比 SpringCache 更加强大的注解,可以原生的支持 TTL、两级缓存、分布式自动刷新,还提供了 Cache接口用于手工缓存操作。 当前有四个实现,RedisCache、TairCache(此部分未在 github 开源)、CaffeineCache(in memory) 和一个简易的 LinkedHashMapCache(in memory),要添加新的实现也是非常简单的。

支持项SpringCacheJetCache
JSR-107支持支持
本地缓存支持支持
远程缓存支持支持
注解缓存支持支持
对象缓存——支持
分布式锁——支持
缓存穿透简单灵活方案支持
缓存击穿简单灵活方案支持
缓存雪崩——灵活方案支持
多级缓存简单灵活方案支持
扩展性支持支持
监控——支持
高级API(异步,原始特性)——支持

上表是由阿里技术提供的与 SpringCache 功能性相关的对比。可以看出 JetCache 功能更加强大,并在许多方面都有着显著的优势。

四、JetCache 快速入门

我们基于 jetcache-starter-redis 包,以注解缓存为例快速带大家体验 JetCache 在处理缓存时有多方便。

4.1 引入 maven 依赖包

<dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-starter-redis</artifactId><version>2.7.5</version>
</dependency>

4.2 编写配置

application.yml 配置文件中添加如下配置:

jetcache:statIntervalMinutes: 15areaInCacheName: falselocal:default:type: linkedhashmapkeyConvertor: fastjsonremote:default:type: rediskeyConvertor: fastjson2broadcastChannel: projectAvalueEncoder: javavalueDecoder: javapoolConfig:minIdle: 5maxIdle: 20maxTotal: 50host: 127.0.0.1port: 6379

4.3 使用 JetCache

  1. 启用注解缓存

    package com.company.mypackage;import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
    import com.alicp.jetcache.anno.config.EnableMethodCache;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
    // 激活 @Cached 注解
    @EnableMethodCache(basePackages = "com.company.mypackage")
    // 激活 @CreateCache 注解
    @EnableCreateCacheAnnotation
    public class MySpringBootApp {public static void main(String[] args) {SpringApplication.run(MySpringBootApp.class);}
    }
  2. 使用注解缓存

    @Service
    public class UserServiceImpl implements UserService {@Resourceprivate UserMapper userMapper;@Override@Cached(name = "cache:user:", key = "#id", expire = 3600, cacheType = CacheType.LOCAL)public User getUserById(Integer id) {return userMapper.selectUserById(id);}
    }
    
  3. 使用效果

    image.png

五、JetCache 功能

5.1 解决缓存穿透

针对缓存穿透,我们通常有两种解决方案:

  1. 缓存空对象
  2. 布隆过滤器

JetCache 采用了第一种方式(即:缓存空对象)来解决缓存穿透问题。我们只需在注解中加上一个属性即可:

@Cached(cacheNullValue = true)

5.2 解决缓存击穿

针对缓存击穿问题,JetCache 提供了两种方式解决:

  1. @CachePenetrationProtect:该注解提供的是 JVM 内存锁级别的保护,旨在将并发重建的请求限制在可控范围。这种方式的核心思想是缓存重建任务可控。
  2. @CacheRefresh:该注解是基于分布式锁的缓存重建,如果对系统的要求较高可采用此种方式。

5.3 解决缓存雪崩

针对缓存雪崩问题,一般在缓存层通过两种方式解决:

  1. 建立多级缓存,多级缓存设置不同过期时间从而形成重叠的数据滑动窗口
  2. 异步维护一块固定缓存,防止缓存失效(兜底方案)

JetCache 针对上面的两种解决方式也给出了对应的方案:

  1. JetCache 可以实现多级缓存
  2. 使用 @CacheRefresh + CacheLoader 维护固定缓存

5.4 实现多级缓存

多级缓存时 JetCache 一大特色,JetCache 多级缓存有以下特点:

  1. JetCache 多级缓存本身可以拥有不同的过期时间,从而构建出多级滑动窗口
  2. JetCache 多级缓存可以简单、直接的避免缓存击穿、缓存雪崩问题
  3. JetCache 默认的注解缓存只支持两级缓存(Local + Remote),但是可以自定义扩展至 N 级
  4. JetCache 缓存可以添加自定义实现的缓存
Cache multiLevelCache = MultiLevelCacheBuilder.createMultiLevelCacheBuilder().addCache(caffeineCache, memCache, redisCache).expireAfterWrite(100, TimeUnit.SECONDS).buildCache();

5.5 缓存失效/更新

有时缓存也是需要管理的。例如:当更新数据库时,使缓存失效或者同步更新缓存。JetCache 可以通过以下两个注解实现缓存失效/更新:

  1. @CacheInvalidate 缓存失效
  2. @CacheUpdate 缓存更新

5.6 编程式创建缓存

之前,我们一直采用注解声明式的创建缓存。但是在某些情况下,我们需要使用编程式创建缓存的方式。JetCache 中可以使用 CacheManager 手动创建缓存。例如:

@Autowired
private CacheManager cacheManager;
private Cache<String, UserDO> userCache;@PostConstruct
public void init() {QuickConfig qc = QuickConfig.newBuilder("userCache").expire(Duration.ofSeconds(100)).cacheType(CacheType.BOTH) // two level cache.syncLocal(true) // invalidate local cache in all jvm process after update.build();userCache = cacheManager.getOrCreateCache(qc);
}

5.7 缓存监控统计

当配置参数 jetcache.statIntervalMinutes 大于 0 时,使用 @CreateCache@Cached 生成的缓存将自带监控。JetCache 会按指定的时间定期通过 logger 输出统计信息。默认输出信息类似如下:
image.png

六、FAQ

本文只简单的介绍了 JetCache 的相关概念,若有特殊开发需求的小伙伴可以自行前去官方文档探索哦。

推荐阅读

  1. 为什么 MySQL 单表数据量最好别超过 2000w
  2. ConcurrentHashMap 源码分析(一)
  3. IoC 思想简单而深邃
  4. ThreadLocal
  5. JDK 动态代理

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

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

相关文章

《从零开始的Java世界》10File类与IO流

《从零开始的Java世界》系列主要讲解Javase部分&#xff0c;从最简单的程序设计到面向对象编程&#xff0c;再到异常处理、常用API的使用&#xff0c;最后到注解、反射&#xff0c;涵盖Java基础所需的所有知识点。学习者应该从学会如何使用&#xff0c;到知道其实现原理全方位式…

LAMP(Linux+Apache+MySQL+PHP)环境介绍、配置、搭建

LAMP(LinuxApacheMySQLPHP)环境介绍、配置、搭建 LAMP介绍 LAMP是由Linux&#xff0c; Apache&#xff0c; MySQL&#xff0c; PHP组成的&#xff0c;即把Apache、MySQL以及PHP安装在Linux系统上&#xff0c;组成一个环境来运行PHP的脚本语言。Apache是最常用的Web服务软件&a…

纸箱码垛机:从传统到智能,科技如何助力产业升级

随着科技的飞速发展&#xff0c;传统工业领域正经历着一场重要的变革。作为物流行业重要一环的纸箱码垛机&#xff0c;其从传统到智能的转型升级&#xff0c;不仅提高了生产效率&#xff0c;还大幅降低了人工成本&#xff0c;为产业升级提供了强大助力。星派将探讨纸箱码垛机的…

【Unity】UnityEvent(一)

​UnityEvent----高效管理游戏事件的利器 在游戏开发中&#xff0c;事件系统是实现各种功能的关键组成部分。它允许我们将不同对象之间的交互解耦&#xff0c;使得代码更加模块化和易于维护。而UnityEvent作为Unity引擎提供的一种强大的事件系统工具&#xff0c;为开发者提供了…

CPDA|0到1突破:构建高效数据分析体系的秘密武器

在现今信息爆炸的时代&#xff0c;数据已经渗透到了我们生活的方方面面&#xff0c;成为了决策、创新和竞争优势的关键。因此&#xff0c;构建一套高效的数据分析体系&#xff0c;对于企业和个人而言&#xff0c;都是至关重要的。那么&#xff0c;如何在众多的数据海洋中脱颖而…

分类神经网络1:VGGNet模型复现

目录 分类网络的常见形式 VGG网络架构 VGG网络部分实现代码 分类网络的常见形式 常见的分类网络通常由特征提取部分和分类部分组成。 特征提取部分实质就是各种神经网络&#xff0c;如VGG、ResNet、DenseNet、MobileNet等。其负责捕获数据的有用信息&#xff0c;一般是通过…

5分钟——测试搭建的springboot接口(二)

5分钟——测试搭建的springboot接口&#xff08;二&#xff09; 1. 查看数据库字段2. 测试getAll接口3. 测试add接口4. 测试update接口5. 测试deleteById接口 1. 查看数据库字段 2. 测试getAll接口 3. 测试add接口 4. 测试update接口 5. 测试deleteById接口

Docker 开启远程安全访问

说明 如果你的服务器是公网IP&#xff0c;并且开放了docker的远程访问&#xff0c;如果没有进行保护是非常危险的&#xff0c;任何人都可以向你的docker中推送镜像、运行实例。我曾开放过阿里云服务器中docker的远程访问权限&#xff0c;在没有开启保护的状态下&#xff0c;几…

用 LMDeploy 高效部署 Llama-3-8B,1.8倍vLLM推理效率

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

Springboot 整合 Quartz框架做定时任务

在Spring Boot中整合Quartz&#xff0c;可以实现定时任务调度的功能 1、首先&#xff0c;在pom.xml文件中添加Quartz和Spring Boot Starter Quartz的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…

一些好听且有心意的英文全名Burwood新南威尔士州伯伍德喝酒上脸就是乙醛中毒1. 康奈尔大学官宣恢复标化要求2. 香港城市大学(东莞)正式设立!

目录 一些好听且有心意的英文全名 Burwood新南威尔士州伯伍德 喝酒上脸就是乙醛中毒 1. 康奈尔大学官宣恢复标化要求 2. 香港城市大学&#xff08;东莞&#xff09;正式设立&#xff01; 一些好听且有心意的英文全名 在选择好听且有意义的英文全名时&#xff0c;我们可…

synchronized的底层原理

目录 介绍 实现原理 对象头 Monitor&#xff08;监视器&#xff09; 锁升级 偏向锁 轻量级锁 重量级锁 锁的优缺点 介绍 synchronized 是 Java 中的关键字&#xff0c;它用于锁定代码块或方法&#xff0c;以确保同一时刻只有一个线程可以进入被锁定的部分。这在多线程…

css盒子设置圆角边框的方法

前言 欢迎来到我的博客 个人主页&#xff1a;北岭敲键盘的荒漠猫-CSDN博客 本文为我整理的设置圆角边框的方法 需求描述 我们在设置盒子边框时&#xff0c;他总是方方正正的。 我们想让这个直直的边框委婉一点该怎么办呢。这个就提到了我们这篇文章讲的东西&#xff1a; bord…

聚观早报 | OpenAI在印度开始招聘;特斯拉将发布一季度财报

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月23日消息 OpenAI在印度开始招聘 特斯拉将发布一季度财报 理想汽车全线产品降价 优酷升级悬疑剧场为白夜剧场 …

ffmpeg支持MP3编码的方法

目录 现象 解决办法 如果有编译包没有链接上的情况 现象 解决办法 在ffmpeg安装包目录下 &#xff0c;通过./configure --list-encoders 和 ./configure --list-decoders 命令可以看到&#xff0c;ffmpeg只支持mp3解码&#xff0c;但是不支持mp3编码。 上网查寻后发现&…

C++ :设计模式实现

文章目录 原则单一职责原则开闭原则依赖倒置原则接口隔离原则里氏替换原则 设计模式单例模式观察者模式策略模式代理模式 原则 单一职责原则 定义&#xff1a; 即一个类只负责一项职责 问题&#xff1a; 类 T 负责两个不同的职责&#xff1a;职责 P1&#xff0c;职责 P2。当…

Tomcat源码解析——一次请求的处理流程

在上一篇文章中&#xff0c;我们知道Tomcat在启动后&#xff0c;会在Connector中开启一个Acceptor(接收器)绑定线程然后用于监听socket的连接&#xff0c;那么当我们发出请求时&#xff0c;第一步也就是建立TCP连接&#xff0c;则会从Acceptor的run方法处进入。 Acceptor&…

使用CSS+HTML完成导航栏

HTML <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>导航栏示例</title> &l…

07 内核开发-避免命名冲突经验技巧分享

07 内核开发-避免命名冲突经验技巧分享 目录 07 内核开发-避免命名冲突经验技巧分享 1.如何在内核开发过程中&#xff0c;避免命名冲突 2. 背景 3.避免方法 4.了解下 文件/proc/kallsyms 5.总结 课程简介&#xff1a; Linux内核开发入门是一门旨在帮助学习者从最基本的…

java-异常

一、异常的概念及分类 Exception&#xff1a;异常&#xff0c;代表程序可能出现的问题 Exception分为两类&#xff1a; 1、运行时异常&#xff1a;RuntimeException以及其子类&#xff0c;编译阶段不会出现异常提醒&#xff0c;在运行阶段会出现异常提醒 2、编译时异常&…