只会一点java

java持续学习者,每月一篇博客。罗列出技术栈,慢慢完善,持续学习,总有一天,你会追上甚至超越曾经的大神。
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

Caffeine缓存算法分析

Posted on 2020-06-17 11:14  只会一点java  阅读(1012)  评论(0)    收藏  举报

一、缓存的思考

二、缓存算法

 

三、Caffeine中的算法剖析

W-TinyLFU由两部分组成:

  1. Window Cache: 窗口缓存LRU回收策略,用于应对突发流量的问题。
  2. Main Cache: 主缓存使用TinyLFU+SLRU回收策略.

  • 1.LRU:窗口缓存,占1%。用来应对突发流量。
  • 2.Filter:sketch 作为过滤器。
  • 3.SLRU:主缓存,占99%。

3.1 W-TinyLFU算法

  • 1.eden初始队列:1%,窗口缓存。
  • 2.SLRU
  •    1)Protected保护队列,它占用主缓存80%空间。
  •    2)Probation缓刑队列,占用主缓存20%空间。

数据流:

  • 1)新数据都会进入Eden。
  • 2)Eden满了,淘汰进入Probation。
  • 3)如果在Probation中被访问,进Protected。
  • 4)Protected满了又会继续降级为Probation。
  • 5)Probation内部进行队头队尾PK,淘汰一个。

3.2 Count-Min Sketch 算法

W-TinyLFU 使用 Count-Min Sketch 算法作为过滤器,该算法是布隆过滤器的一种变种

Count-Min Sketch 算法:

根据不同的hash算法创建不同的数组,针对每一个数据进行多次hash,并在该hash算法的对应数组hash索引位置上+1,由于hash算法存在冲突,那么在最后取计数的时候,取所有数组中最小的值即可。

原理:一个hash函数碰撞几率较大,多个hash函数同时碰撞几率指数下降。

3.3 RingBuffer 算法

Caffeine缓存库在并发控制方面采用了RingBuffer和 MpscChunkedArrayQueue 来实现多生产者-单消费者队列。

RingBuffer通过将数据分段存储,并使用分段锁( StripedBuffer )来分散竞争,进一步优化了并发性能‌

---高性能无锁队列Disruptor的核心算法。

1.写操作是所有线程共享一个Ringbuffer。

2.读操作比写操作更加频繁,进一步减少竞争,其为每个线程配备了一个RingBuffer.

 ---参考---

https://mp.weixin.qq.com/s/VkcwhWwHYrNu-yWKPxteZA