新一代缓存Caffeine,速度确实比Guava的Cache快

栏目: IT技术 · 发布时间: 3年前

内容简介:推荐阅读:

新一代缓存Caffeine,速度确实比Guava的Cache快

不羡鸳鸯不羡仙,一行代码调半天。原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

我想把记忆缓存起来,等再次见到你,就能够很快认出你。

能够说出这么有哲理的话,得益于我对缓存的理解,以及对它的看重。没有了缓存,我的人生就没有了意义。

缓存是非常重要的,工作中大部分工作可以说是和缓存打交道。由于使用广泛,所以针对缓存系统的任何优化,如果能够提高一丁点儿性能,就会让人无比兴奋。

很长一段时间,我都在用 GuavaLoadingCache 。它和 ConcurrentHashMap 是非常像的,但在其上封装了一些好用的逐出策略和并发优化,就显得好用的多。

今天主要说的是 Caffeine ,中文名就是咖啡因,一种容易让人精神亢奋的物质。它可以说是Guava的重写,但是效率却非常的高,青出于蓝而胜于蓝。

下图是Caffeine的一张性能测试图。可以看到它的性能,甩了GuavaCache老远。这是为什么呢?

新一代缓存Caffeine,速度确实比Guava的Cache快

首先要从它的作者开始说起。作者的github是( https://github.com/ben-manes ),曾经写了 ConcurrentLinkedHashMap 这个类,而这个类又是GuavaCache的基础。 Ben Manes 一拍脑袋,决定更上层楼。

为什么说Caffeine好?

后浪Caffeine一来,GuavaCache就已经OUT了。

Caffeine支持异步加载方式,直接返回 CompletableFutures ,相对于GuavaCache的同步方式,它不用阻塞等待数据的载入。另外,它的编程模型是友好的,省去了很多重复的工作。

GuavaCache是基于LRU的,而Caffeine是基于LRU和LFU的,结合了两者的优点。对这两个算法不太清楚的同学,可以参考xjjdog之前的文章: 《3种堆内缓存算法,赠源码和设计思路》

两者合体之后,变成了新的 W-TinyLFU 算法,它的命中率非常高,内存占用更加的小,这是主要原因所在。

Caffeine另外一个比较快的原因,就是很多操作都使用了异步,把这些事件提交到队列里。队列使用的 RingBuffer ,看到这个名词,我不自觉的想到了 lmaxDisruptor ,它已经成了无锁高并发的代名词。

测试命中率

我们决定拿线上的数据进行验证一下。事实上,大部分比较重要的Cache,我都已经使用Caffeine替换了,完成了骚气的升级。

由于它们的 API 长得非常像,这个过程是无痛的,连麻药都不需要打。

其中有个业务,有一个大的堆内缓存,缓存了用户数据。里面包含用户名、性别、地址、积分等属性,形成了一个JSON对象,但大小不超过1KB。通过灰度,根据不同的策略,我们测试了它的实际命中率。

策略1

  • 最大缓存 1w 用户
  • 数据进入缓存后,5分钟失效(需要重新读取)

命中率:

  • Caffeine 29.22 %

  • Guava 21.95%

策略2

  • 加大缓存数据量到6w用户

  • 数据进入缓存后,20分钟失效,这个和Session有的一拼了

命中率(依然是高一筹):

  • Caffeine 56.04 %

  • Guava 50.01%

策略3

  • 直接加大缓存到15w用户

  • 数据进入缓存后,30分钟失效

此时的命中率:

  • Caffeine 71.10 %

  • Guava 62.76%

Caffeine的命中率一直是领先的。命中率高,效率自然也就高。调整到50%以上,我们的缓存作用就很大了。

异步载入

再放上官方的两张测试图:

(1) Read (75%) / Write (25%)

新一代缓存Caffeine,速度确实比Guava的Cache快

(2) Write (100%)

新一代缓存Caffeine,速度确实比Guava的Cache快

(3) Read (100%)

新一代缓存Caffeine,速度确实比Guava的Cache快

我们一直在提Caffeine的异步加载。那代码到底长什么样子呢?异步加载缓存使用了响应式编程模型,返回的是 CompletableFuture 对象。说实话,代码长得和Guava很像。

public static void main(String[] args) {
        AsyncLoadingCache<String, String> asyncLoadingCache = Caffeine.newBuilder()
                .maximumSize(1000)
                .buildAsync(key -> slowMethod(key));

        CompletableFuture<String> g = loadingCache.get("test");
        String value = g.get();
    }

    static String slowMethod(String key) throws Exception {
        Thread.sleep(1000);
        return key + ".result";
    }

我记得前段时间翻Spring的源码时,也看到过它。

新一代缓存Caffeine,速度确实比Guava的Cache快

在SpringBoot里,通过提供一个 CacheManager 的Bean,即可与 Springboot-cache 进行集成,可以说是很方便了。

关键代码。

//bean生成
@Bean("caffeineCacheManager")
public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCaffeine(Caffeine.newBuilder() .maximumSize(1000));
    return cacheManager;
}

//使用注入
@CacheConfig(cacheNames = "caffeineCacheManager")

//信息缓存
@Cacheable(key = "#id")

技术框架这么多,何时是尽头。

作者简介: 小姐姐味道 (xjjdog),一个不允许 程序员 走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。交流。

后台回复“ 加群 ”,带你进入高手如云交流群

推荐阅读:


以上所述就是小编给大家介绍的《新一代缓存Caffeine,速度确实比Guava的Cache快》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Trading and Exchanges

Trading and Exchanges

Larry Harris / Oxford University Press, USA / 2002-10-24 / USD 95.00

This book is about trading, the people who trade securities and contracts, the marketplaces where they trade, and the rules that govern it. Readers will learn about investors, brokers, dealers, arbit......一起来看看 《Trading and Exchanges》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码