Caffeine

Caffeine

Caffeine简介

  • Caffeine 是基于Java 8的高性能,接近最佳的缓存库。 Caffeine使用Google Guava的API提供内存缓存。
  • 在Caffeine中分为两种缓存,一个是有界缓存,一个是无界缓存,无界缓存不需要过期并且没有界限。
    //下面创建的是无界缓存
    Cache<String,String> cache = Caffeine.newBuilder().build();
    //下面创建的是有界缓存
    Cache<String,String> cache = Caffeine.newBuilder()
            .maximumSize(100).build();

Caffeine使用

  • maven使用Caffeine
    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
        <version>2.6.2</version>
    </dependency>
  • 简单使用方式
    Cache<String,String> cache = Caffeine.newBuilder()
                .expireAfterWrite(100, TimeUnit.SECONDS)
                .maximumSize(200)
                .build();
- expireAfterWrite设置缓存在100秒内未写入会过期
- maximumSize设置最大长度为200,单位是MB

Caffeine与其他缓存对比

Caffeine原理

  • Caffeine是基于 TinyLFU 实现的

Windows-TinyLFU

LFU、LRU、FIFO
  • FIFO:first in first out。先进先出。判断被存储的时间,离目前最远的数据
    优先被淘汰
  • LRU:least recently used。最近最少使用。判断最近被使用的时间最远的数据优先被淘汰
  • LFU:least frequently used。最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。
Windows-TinyLFU演变
  • 传统的LFU收时间周期的影响比较大。所以各种LFU的变种出现了,基于时间周期进行衰减,或者在最近某个时间段内的频率。同样的LFU也会使用额外空间记录每一个数据访问的频率,即使数据没有在缓存中也需要记录,所以需要维护的额外空间很大。
  • 命中率最高的策略就是 LFU,但是 LFU 有两个缺点:1. 需要维护比较大的元数据(比如说 key 的频数统计,缓存根据元数据来决定那些 key 需要清退);2. 频数变化可能会很快。
  • 再回到LRU,我们的LRU也不是那么一无是处,LRU可以很好的应对突发流量的情况,因为他不需要累计数据频率。
  • 所以W-TinyLFU结合了LRU和LFU,以及其他的算法的一些特点。
  • TinyLFU的改进之处
    • 1.对某个 key 是否放入缓存,有一个准入策略,需要判断把 key 放进缓存有利才会放;
    • 2.更紧凑的数据结构

Caffeine比guava性能高的原因

  • 在guava cache中读写操作夹杂着过期时间的处理,也就是在一次put操作中有可能还会做淘汰策略,所以其读写性能会受到一定影响。而Caffeine在读写操作上比guava高的原因在于Caffeine对淘汰策略的操作是异步操作(注意读写操作仍然是同步操作),他将事件提交至队列(RingBuffer)。然后会通过默认的ForkJoinPool.commonPool(),或者自己配置线程池进行取队列操作,然后再进行后续的淘汰,过期操作。
  • 当然读写也是有不同的队列,在Caffeine中认为缓存读比写多很多,所以对于写操作时所有线程共享一个Ringbuffer。对于读操作,为每个线程配备了一个RingBuffer

Caffeine数据淘汰策略

  • 在Caffeine所有的数据都在ConcurrentHashMap中,这个和guava cache不同,guava cache是自己实现了个类似ConcurrentHashMap的结构。在Caffeine中有三个记录引用的LRU队列

    • Eden队列:在Caffeine中规定只能为缓冲容量的1%。这个队列中记录的是新到的数据,防止突发流量由于之前没有访问频率,从而导致被淘汰。
    • Probation队列:称为缓刑队列,在这个队列就代表数据相对较冷,马上就要淘汰了。有效大小为size-eden队列大小-protected大小
    • Protected队列:保护队列有效大小为(size-eden队列大小)×80%
  • 淘汰策略

    • 新数据进来首先进入Eden区,那么就算有突发的访问频率,也不会把这些数据给冲掉
    • 被访问过一次以上数据会从Eden进入Probation,Probation称为缓刑区,一旦没有晋升到Protected,那么这个区的数据最有可能先死
    • 从Probation的数据再被访问时会进入Protected区,在这个区称为保护区,这里的数据相对安全,但是一旦Protected区数据满了,被淘汰的数据,又会回到Probation区
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值