漫谈缓存架构
背景
当前提起缓存估计又很多同学的第一反应就是Redis。的确Redis 的确可以作为缓存,而且引入redis 作为缓存是一种很重要的技术手段,但是只是这样距离真正掌握缓存架构还有一段距离,下文中会主要介绍缓存设计中的重要核心思路,大部分是文中会以Caffeine 为例介绍
假设
绝大多数缓存的设计都是基于一种读多写少的场景进行设计, 只有在这种场景下才会需要使用缓存技术进行优化。
淘汰算法
进程内缓存我们可以通过 Hash类型的Map 来实现(C++通常使用unordered_map、Java使用HashMap实现)。不过,Java 进程内存是有限的,不可能无限地往里面放缓存对象。这就需要有合适的算法辅助我们淘汰掉使用价值相对不高的对象,为新进的对象留有空间。常见的缓存淘汰算法有 FIFO、LRU、LFU。
-
FIFO: 它是优先淘汰掉最先缓存的数据、是最简单的淘汰算法。
- 缺点:如果先缓存的数据使用频率比较高的话,那么该数据就不停地进进出出,因此它的缓存命中率比较低。
-
LRU: 它是优先淘汰掉最久未访问到的数据。
- 缺点:是不能很好地应对偶然的突发流量,短期缓存会被的突发流量会完全刷掉
-
LFU: 最近最少频率使用。它是优先淘汰掉最不经常使用的数据,需要维护一个表示使用频率的字段。
- 缺点1:如果访问频率比较高的话,内存消耗比较高;
- 缺点2:新上的热点数据更新不合理,比如某个歌手的老歌播放历史较多,新出的歌如果和老歌一起排序的话,就永无出头之日。
-
W-TinyLFU :解决了 LRU 和LFU上述的缺点。W-TinyLFU 算法由论文**《TinyLFU: A Highly Efficient Cache Admission Policy》**提出, Caffeine 使用了 W-TinyLFU 算法。
W-TinyLFU详解
- 采用 Count–Min Sketch 算法降低频率信息带来的内存消耗;
- 维护一个PK机制保障新上的热点数据能够缓存。
Count-Min Sketch
与bloom filter 异同点:
- 同:大家都是用多个hash函数计算
- 异:
- bloom filter 作用在一个大空间内部,只能判断true OR False, 对于带频率的计算不准确。
- Count-Min Sketch 分成多个子空间进行计算,由于由多路hash保证,最终计算的结果准确率相对较高,并且可以计算。
PK 机制
- Rest 衰减 :对于所有key的访问频率之和有个最大值,当达到最大值时,会进行reset即对各个缓存key的频率除以2
- 三阶段:通过对访问队列分成三段,这样避免了新加入的热点数据早早地被淘汰掉。
读写性能
在caffeine中认为缓存读比写多很多,所以对于写操作是所有线程共享一个Ringbuffer。
读
读完把数据放到环形队列 RingBuffer 中,为了减少读并发,采用多个 RingBuffer,每个线程都有对应的 RingBuffer。
写
与读缓冲类似,写缓冲是为了储存写事件。读缓冲中的事件主要是为了优化驱逐策略的命中率,因此读缓冲中的事件完整程度允许一定程度的有损。但是写缓冲并不允许数据的丢失,因此其必须实现为一个安全的队列。Caffeine 写是把数据放入MpscGrowableArrayQueue 阻塞队列中,它参考了JCTools里的MpscGrowableArrayQueue ,是针对 MPSC- 多生产者单消费者(Multi-Producer & Single-Consumer)场景的高性能实现。多个生产者同时并发地写入队列是线程安全的,但是同一时刻只允许一个消费者消费队列。
参考
|标题|链接|
|-----|
|LFU基本原理和实现|https://www.cnblogs.com/wyq178/p/11790015.html|
|高性能缓存 Caffeine 原理及实战|https://www.modb.pro/db/44421|
|深入解密来自未来的缓存-Caffeine|https://juejin.cn/post/6844903670014803981|
|caffeine代码库|https://github.com/ben-manes/caffeine|
|缓存架构设计|https://m.w3cschool.cn/architectroad/architectroad-cache-architecture-design.html|
|redis实践与性能总结|https://segmentfault.com/a/1190000037438994|
|Bloom Filter 和 Count-Min Sketch 介绍|https://titanssword.github.io/2018-02-23-Bloom%20Filter%20and%20Count-Min%20Sketch.html|