微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
多级缓存
文章目录
- 微服务框架
- 多级缓存
- 46 JVM 进程缓存
- 46.3 初识Caffeine
- 46.3.1 本地进程缓存
- 46.3.2 Caffeine 示例
 
 
 
 
46 JVM 进程缓存
46.3 初识Caffeine
46.3.1 本地进程缓存
缓存在日常开发中启动至关重要的作用,由于是存储在内存中,数据的读取速度是非常快的,能大量减少对数据库的访问,减少数据库的压力。我们把缓存分为两类:
-  分布式缓存【往往用在集群的环境下】,例如Redis: - 优点:存储容量更大、可靠性更好、可以在集群间共享
- 缺点:访问缓存有网络开销
- 场景:缓存数据量较大、可靠性要求较高、需要在集群间共享
 
-  进程本地缓存,例如HashMap【其实我们之前也写过】、GuavaCache: - 优点:读取本地内存,没有网络开销,速度更快
- 缺点:存储容量有限、可靠性较低、无法共享
- 场景:性能要求较高,缓存数据量较小
 
【我们要学着用的是Caffeine】
Caffeine是一个基于Java8开发的,提供了近乎最佳命中率的高性能的本地缓存库。目前Spring内部的缓存使用的就是Caffeine。
GitHub地址:https://github.com/ben-manes/caffeine


官方文档说明:

【算了,英文不好】
46.3.2 Caffeine 示例
可以通过item-service项目中的单元测试来学习Caffeine的使用:

试试
/*
  基本用法测试
 */
@Test
void testBasicOps() {
    // 创建缓存对象
    Cache<String, String> cache = Caffeine.newBuilder().build();
    // 存数据
    cache.put("gf", "迪丽热巴");
    // 取数据,不存在则返回null
    String gf = cache.getIfPresent("gf");
    System.out.println("gf = " + gf);
    // 取数据,不存在则去数据库查询
    String defaultGF = cache.get("defaultGF", key -> {
        // 这里可以去数据库根据 key查询value
        return "柳岩";
    });
    System.out.println("defaultGF = " + defaultGF);
}

测试运行

OK,绿了,这就是Caffeine 库的简单使用
Caffeine提供了三种缓存驱逐策略:
- 基于容量:设置缓存的数量上限

测试代码:
/*
 基于大小设置驱逐策略:
 */
@Test
void testEvictByNum() throws InterruptedException {
    // 创建缓存对象
    Cache<String, String> cache = Caffeine.newBuilder()
            // 设置缓存大小上限为 1
            .maximumSize(1)
            .build();
    // 存数据
    cache.put("gf1", "柳岩");
    cache.put("gf2", "范冰冰");
    cache.put("gf3", "迪丽热巴");
    // 延迟10ms,给清理线程一点时间
    Thread.sleep(10L);
    // 获取数据
    System.out.println("gf1: " + cache.getIfPresent("gf1"));
    System.out.println("gf2: " + cache.getIfPresent("gf2"));
    System.out.println("gf3: " + cache.getIfPresent("gf3"));
}
运行结果
如果我现在不给他清理的时间

OK,可以看到三个还是都拿到了 ,说明它还没来得及清理,你就读了
给它清理时间

OK,这样就只能拿到最后一个 了
- 基于时间:设置缓存的有效时间

测试代码
/*
 基于时间设置驱逐策略:
 */
@Test
void testEvictByTime() throws InterruptedException {
    // 创建缓存对象
    Cache<String, String> cache = Caffeine.newBuilder()
            .expireAfterWrite(Duration.ofSeconds(1)) // 设置缓存有效期为 10 秒
            .build();
    // 存数据
    cache.put("gf", "柳岩");
    // 获取数据
    System.out.println("gf: " + cache.getIfPresent("gf"));
    // 休眠一会儿
    Thread.sleep(1200L);
    System.out.println("gf: " + cache.getIfPresent("gf"));
}
运行结果

- 基于引用:设置缓存为软引用或弱引用,利用GC来回收缓存数据。性能较差,不建议使用。
在默认情况下,当一个缓存元素过期的时候,Caffeine不会自动立即将其清理和驱逐。而是在一次读或写操作后,或者在空闲时间完成对失效数据的驱逐。
OK, 这就是Caffeine 的简单认识

















