首页 > 数据库 >【缓存】J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架的使用方法

【缓存】J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架的使用方法

时间:2023-06-09 11:02:59浏览次数:70  
标签:缓存 Java Redis j2cache 使用 J2Cache 摄像头


本文目录

一、J2Cache简介

二、数据读取

三、使用方法及实际示例

3.1 引用 Maven

3.2 准备配置

3.3 编写代码

3.3.1 Demo示例

3.3.2 实际案例

四、常见问题

4.1 J2Cache 的使用场景是什么?

4.2 为什么不能在程序中设置缓存的有效期

4.3 如何使用 memcached 作为二级缓存

4.4 使用何种 Redis 的存储模式最佳? generic 还是 hash ?


一、J2Cache简介

J2Cache 是 OSChina 目前正在使用的两级缓存框架(要求至少 Java 8)。第一级缓存使用内存(同时支持 Ehcache 2.x、Ehcache 3.x 和 Caffeine),第二级缓存使用 Redis(推荐)/Memcached 。 由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。 该缓存框架主要用于集群环境中。单机也可使用,用于避免应用重启导致的缓存冷启动后对后端业务的冲击。

J2Cache 从 1.3.0 版本开始支持 JGroups 和 Redis Pub/Sub 两种方式进行缓存事件的通知。在某些云平台上可能无法使用 JGroups 组播方式,可以采用 Redis 发布订阅的方式。详情请看 j2cache.properties 配置文件的说明。

视频介绍:http://v.youku.com/v_show/id_XNzAzMTY5MjUy.html

J2Cache 的两级缓存结构

L1: 进程内缓存(caffeine\ehcache)
L2: Redis/Memcached 集中式缓存

二、数据读取

  1. 读取顺序 -> L1 -> L2 -> DB
  2. 数据更新
    1 从数据库中读取最新数据,依次更新 L1 -> L2 ,发送广播清除某个缓存信息
    2 接收到广播(手工清除缓存 & 一级缓存自动失效),从 L1 中清除指定的缓存信息

三、使用方法及实际示例

J2Cache 默认使用 Caffeine 作为一级缓存,使用 Redis 作为二级缓存。你还可以选择 Ehcache2 和 Ehcache3 作为一级缓存。

以下实际的使用示例是以Springboot 项目为基础集成 J2Cache 的。

3.1 引用 Maven

以下是我从中央仓库查看的2.8.x的版本


<!--
        <dependency>
            <groupId>net.oschina.j2cache</groupId>
            <artifactId>j2cache-core</artifactId>
            <version>2.8.2-release</version>
        </dependency>


3.2 准备配置

拷贝 j2cache.properties 和 caffeine.properties 到你项目的源码目录,并确保这些文件会被编译到项目的 classpath 中。如果你选择了 ehcache 作为一级缓存,需要拷贝 ehcache.xml 或者 ehcache3.xml 到源码目录(后者对应的是 Ehcache 3.x 版本),这些配置文件的模板可以从 https://gitee.com/ld/J2Cache/tree/master/core/resources 这里获取。

使用你喜欢的文本编辑器打开 j2cache.properties 并找到 redis.hosts 项,将其信息改成你的 Redis 服务器所在的地址和端口。

我们建议缓存在使用之前都需要预先设定好缓存大小及有效时间,使用文本编辑器打开 caffeine.properties 进行缓存配置,配置方法请参考文件中的注释内容。

例如:default = 1000,30m #定义缓存名 default ,对象大小 1000,缓存数据有效时间 30 分钟。 你可以定义多个不同名称的缓存。

自己代码中实际的配置文件已上传至资源中心,方便查看:




【缓存】J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架的使用方法_J2Cache



J2Cache 使用Ceffien作为一级缓存,使用Redis作为二级缓存时的配置

3.3 编写代码

3.3.1 Demo示例


public static void main(String[] args) {

    CacheChannel cache = J2Cache.getChannel();
    
    // 缓存操作
    cache.set("default", "1", "Hello J2Cache");
    System.out.println(cache.get("default", "1"));

    // 清除缓存
    cache.evict("default", "1");
    System.out.println(cache.get("default", "1"));
    
    // 请注意 cache.close() 方法只需在程序退出时调用
    cache.close();
}


3.3.2 实际案例


/**
     * 获取摄像头的uuid
     *
     * @param sn       家庭的sn
     * @param deviceId 像头的设备id
     * @return 摄像头的uuid
     */
    private String getUuid(String sn, Integer deviceId) {
        log.info("E|CameraShoutHandler|getUuid()|根据sn和摄像头的设备id调用设备云服务查询摄像头详情开始!");
        long startTime = System.currentTimeMillis();
        
        // 格式 dev225:132
        String key = sn + StrUtil.COLON + deviceId;

        CacheChannel channel = J2Cache.getChannel();
        // 先从缓存中取出摄像头的UUID(首先从内存中读取,内存中如果没有再从Redis中读取,如果Redis还是没有,那么就再去数据库或者调用第三方服务获取数据)
        CacheObject cacheObject = channel.get(SystemConstant.APPLICATION_NAME, key);
        String uuid = (String) cacheObject.getValue();
        // 如果两级缓存中没有摄像头的uuid,则去调用设备云服务查询摄像头的详情,查询出之后再存入缓存
        if (Objects.isNull(uuid)) {
            log.info("**************** 缓存中的UUID为空,调用设备云服务查询摄像头的uuid *************");
            CommResponse cameraDetailInfo = cameraDetailInfoRpc.getCameraDetailInfo(sn, deviceId);
            CameraDetailInfoDTO cameraDetailInfoDTO = (CameraDetailInfoDTO) cameraDetailInfo.getData();
            // 存入缓存
            channel.set(SystemConstant.APPLICATION_NAME, key, cameraDetailInfoDTO.getUuid());
        }

        log.info("E|CameraShoutHandler|getUuid()|根据sn和摄像头的设备id调用设备云服务查询摄像头详情结束!------------ 耗时:【{}】毫秒!", System.currentTimeMillis() - startTime);

        return uuid;
    }


可以从Redis客户端工具里查看,Redis中已经有这个数据了。

【缓存】J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架的使用方法_redis_02

 

四、常见问题

4.1 J2Cache 的使用场景是什么?

首先你的应用是运行在集群环境,使用 J2Cache 可以有效降低节点间的数据传输量;其次单节点使用 J2Cache 可以避免应用重启后对后端业务系统的冲击

4.2 为什么不能在程序中设置缓存的有效期

在程序中定义缓存数据的有效期会导致缓存不可控,一旦数据出问题无从查起,因此 J2Cache 的所有缓存的有效期都必须在 一级缓存 的配置中预设好再使用

4.3 如何使用 memcached 作为二级缓存

首先修改 j2cache.properties 中的 j2cache.L2.provider_class 为 memcached,然后在 j2cache.properties 中配置 memcached.xxx 相关信息。

需要在项目中引入对 memcached 的支持:


<dependency>
    <groupId>com.googlecode.xmemcached</groupId>
    <artifactId>xmemcached</artifactId>
    <version>2.4.5</version>
</dependency>


4.4 使用何种 Redis 的存储模式最佳? generic 还是 hash ?

我们推荐使用 generic 存储模式,这也是 J2Cache 默认的存储模式,hash 模式最大的问题是无法单独对 key 进行 expire 设置。

参考资料:J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架

完结!

标签:缓存,Java,Redis,j2cache,使用,J2Cache,摄像头
From: https://blog.51cto.com/no8g/6445902

相关文章

  • java注解详解及示例
    本文简单介绍java的注解原理与示例。(文章目录)一、基本语法1、声明注解与元注解我们先来看看前面的org.junit.Test注解是如何声明的//声明Test注解@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public@interfaceTest{staticclassNoneextend......
  • 深入浅出Spring原理及实战「缓存Cache开发系列」
    1.  缓存Cache的概念和作用在现代软件开发中,缓存已经成为了一个非常重要的概念。缓存是指将数据存储在一个临时的存储器中,以便于快速访问和读取。缓存的作用是提高系统的性能和响应速度,减少网络流量和数据库的负载。以电影院购票为例,当用户选择一部电影时,系统需要查询电影的......
  • 怎样用Java来获取真实的IP地址
    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。如果使用了反向代理软件,将http://192.168.1.110:2046/的URL反向代理为http://www.bt285.cn/的URL时,......
  • java 实现对象排序,实现java对象排序的三种方式
    1.自然排序:要排序的对象类实现Comparable<>接口,重写其compareTo()方法,方法体中实现对象的比较大小规则2.自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现compare()其方法;然后将比较器对象c传给Collections.sort()方法的参数列表中,实现排序功能,......
  • Web前端和Java哪个好?
    学Web前端好还是学Java好?这是一个常见的问题,两者都是非常有前途的领域,并且都有自己的长处和优势。在选择之前,需要先了解两个方向的发展前景和技能要求。下面我们从以下几个方面进行比较。 1、薪资待遇就薪资待遇而言,Java开发人员的薪资通常较高,特别是在大型公司和金融领域。根据Pa......
  • Java理论和实践:用软引用阻止内存泄漏
    在本文中,他将解释Reference对象的另外一种形式,即软引用(softreferences),用于帮助垃圾收集器管理内存使用和消除潜在的内存泄漏。垃圾收集可以使Java程序不会出现内存泄漏,至少对于比较狭窄的“内存泄漏”定义来说如此,但是这并不意味着我们可以完全忽......
  • javaScript通用数据类型校验_1
    /***取得字符串的字节长度*/1.functionstrlen(str)2.{3.vari;4.varlen;5.6.len=0;7.for(i=0;i<str.length;i++)8.{9.if(str.charCodeAt(i)>255)len+=2;elselen++;10.}11......
  • JAVA面试题解惑系列(六)——字符串(String)杂谈
    关键字:java面试题字符串string作者:臧圩人(zangweiren)网址:http://zangweiren.javaeye.com上一次我们已经一起回顾了面试题中常考的到底创建了几个String对象的相关知识,这一次我们以几个常见面试题为引子,来回顾一下String对象相关的其它一些方面。String的l......
  • java关键字native、static、final详解
    native: native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。JNI是Java本机接口(JavaNativeInterface),是一个本......
  • 关于redis在我们数据平台升级版本时出现的问题
    redis启动原来我们是用写死的代码后来统一使用了启动脚本这就导致了redis存储的问题 我们知道,redis在默认情况(appendonlyno)下是使用快照存储,然而在写死的代码中,快照存储的位置是rootPath(我们的数据产品的根路径)大概更新了三个版本之后,bat脚本启动的位置是根路径\redis路径......