缓存神器-JetCache

news2025/3/15 19:09:23

序言

今天和大家聊聊阿里的一款缓存神器 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: 15
  areaInCacheName: false
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      keyConvertor: fastjson2
      broadcastChannel: projectA
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: 127.0.0.1
      port: 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 {
    
        @Resource
        private 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.coloradmin.cn/o/1622653.html

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

相关文章

电商技术揭秘三十一:智能风控与反欺诈技术

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘二十八&#xff1a;安全与合规性保障 电商技术揭秘二十九&#xff1a;电商法律合规浅析 电商技术揭秘三十&#xff1a;知识产权保…

全光谱灯对人体的危害?谨记全光谱灯选购要避开的四大套路

全光谱灯对人体的危害有多大&#xff1f;近年来网上关于护眼台灯对视力有害的言论有很多&#xff0c;引发了很多人空前的关注&#xff0c;事实上这未必是一件坏事&#xff0c;因为随着护眼台灯的热度持续上涨&#xff0c;市面上浑水摸鱼的行为增多了不少&#xff0c;有着不少劣…

不要摆摊,不要开早餐店,原因如下

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 我最近开通了视频号会员专区嘛&#xff0c;专区有个问答功能可以提问&#xff0c;有个会员问了我问题&#xff0c;其中一条问答分享给大家&#xff1a; 松哥&#xff0c;突然想去兼职&#xff0c;早上卖点杂粮煎饼果…

像素着色技术在AI去衣中的深度应用与探索

在人工智能&#xff08;AI&#xff09;领域&#xff0c;图像处理技术一直是一个热门且充满挑战的研究方向。其中&#xff0c;AI去衣技术作为图像处理技术的一个分支&#xff0c;近年来引起了广大研究者和公众的广泛关注。本文将重点探讨像素着色技术在AI去衣中的重要作用&#…

深度学习图像生成在AI去衣技术中的应用与探索

随着人工智能技术的迅猛发展&#xff0c;深度学习在图像生成领域的应用越来越广泛。其中&#xff0c;AI去衣技术作为深度学习在图像处理中的一个新兴分支&#xff0c;引起了广大科研人员和公众的关注。本文将深入探讨深度学习图像生成在AI去衣技术中的作用&#xff0c;并尝试解…

那些你不知道的数据库知识:行式存储和列式存储

前几天听课&#xff0c;听到老师讲数据列式存储。 我&#x1f64b;&#x1f3fb;‍♀️&#xff1a;等等&#xff0c;what&#xff0c;什么列式存储&#xff0c;数据一行一行的展示&#xff0c;然后一行一行的存在数据库里面不就好了&#xff0c;什么叫做列式存储&#xff0c;…

前端中不同格式的日期相互转换(字符串、时间戳)js相关

在项目中遇到了&#xff0c;需要实现字符串和Unix时间戳的相互转换&#xff0c;随手记录一下。 我使用的组件库为Naive UI&#xff0c;涉及到的组件为日期选择器&#xff08;Date Picker&#xff09;。作者在文档中写道&#xff1a; 实话说我不喜欢这个 feature&#xff0c;因为…

训练营第三十三天贪心(第五部分重叠区间问题)

训练营第三十三天贪心&#xff08;第五部分重叠区间问题&#xff09; 435.无重叠区间 力扣题目链接 题目 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: …

TapData + 实时数仓:实时数据如何赋能船舶制造业,助力数字化应用升级和科学管理运营

使用 TapData&#xff0c;化繁为简&#xff0c;摆脱手动搭建、维护数据管道的诸多烦扰&#xff0c;轻量代替 OGG、DSG 等同步工具&#xff0c;「CDC 流处理 数据集成」组合拳&#xff0c;加速仓内数据流转&#xff0c;帮助企业将真正具有业务价值的数据作用到实处&#xff0c…

笔试狂刷--Day5(最小公倍数+最优路径)

大家好,我是LvZi,今天带来笔试狂刷--Day5 一.求最小公倍数 链接:求最小公倍数 分析: 数学知识–辗转相除法(迭代/递归) 代码: import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args)…

计算机视觉——两视图几何求解投影矩阵

上文我提到了通过图像匹配得到基本矩阵&#xff0c;接下来我们要接着求解投影矩阵。 计算投影矩阵思路 假设两个投影矩阵为规范化相机&#xff0c;因此采用基本矩阵进行恢复。在规范化相机下&#xff0c; P [ I ∣ 0 ] P[I|0] P[I∣0], P ′ [ M ∣ m ] P[M|m] P′[M∣m]。…

【结构型模型】享元模式

一、享元模式概述 享元模式定义&#xff1a;又叫蝇量模式&#xff0c;运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象&#xff0c;而这些对象都很相似&#xff0c;状态变化很小&#xff0c;可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细…

创建SpringBoot和RabbitMQ的整合项目

文章目录 创建SpringBoot和RabbitMQ的整合项目首先快速创建一个maven项目引入SpringBoot整合rabbitMQ的依赖在src/main目录下创建resources目录并引入配置文件写消息发送者MessageSender写消息接收者MessageReceiver写RabbitMQConfig配置类写SpringBoot启动主类CommandLineRunn…

Bootloader应用启动分析详解

内存->磁盘 引导程序->核心->根文件系统rootfs->app 引导程序加载最重要 由于boot设计比较偏底层,所以根据CPU架构和OS类型可能有所不同 uboot是对CPU架构和OS类型支持得比较多得一种开源引导程序 Bootloader的种类 s5p6818启动流程 芯片最开始是从iROM启动,…

【漏洞复现】泛微e-Mobile 移动管理平台文件上传漏洞

0x01 阅读须知 “如棠安全的技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供…

大型企业不同安全域文件交换,常见方式的优势与问题对比

现在越来越多的企业通过对网络进行物理或逻辑隔离&#xff0c;将内部网络与外部网络隔离开来&#xff0c;从而限制非法访问和恶意渗透&#xff0c;防止敏感数据泄露和恶意代码的传播&#xff0c;提高网络安全性。对于大型企业而言&#xff0c;将网络分为内外网并不足以满足安全…

Redis底层数据结构之IntSet

目录 一、概述二、IntSet结构三、自动升级 redis底层数据结构已完结&#x1f44f;&#x1f44f;&#x1f44f;&#xff1a; ☑️redis底层数据结构之SDS☑️redis底层数据结构之ziplist☑️redis底层数据结构之quicklist☑️redis底层数据结构之Dict☑️redis底层数据结构之Int…

UNet网络在图像去模糊方向的应用

前一段时间&#xff0c;我们学习了关于UNet网络的结构和基于UNet网络的去模糊网络MIMO-UNet&#xff0c;DeepRFT等网络的结构&#xff0c;大致的对网络的结构组成和实现过程有了一定的了解&#xff0c;下面考虑在图像去模糊部分&#xff0c;基于UNet的已有的研究工作&#xff0…

【力扣】螺旋矩阵

59. 螺旋矩阵 II 刚开始遇到这道题目的时候相信没见过的同学多多少少都会有点懵圈&#xff0c;感觉题目有点无从下手&#xff0c;但其实只要抓住本质就行了&#xff0c;题目的最终目的就是返回一个二维数组的结果&#xff0c;这个二维数组的大小是的 int[n][n]&#xff0c;题目…

Linux-线程互斥和死锁

目录 一.线程互斥 1.1 进程线程间的互斥相关背景概念 1.2 互斥量mutex 二.互斥量的接口 2.1 初始化互斥量 2.2 销毁互斥量 2.3 互斥量加锁和解锁 2.4 改进后售票代码 三.死锁 3.1.什么是死锁&#xff1f; 3.2.死锁四个必要条件 3.3 避免死锁 一.线程互斥 1.1 进程…