漫谈缓存架构

漫谈缓存架构

背景

当前提起缓存估计又很多同学的第一反应就是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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pQphTdFB-1632024843953)(http://bos.bj.bce-internal.sdns.baidu.com/agroup-bos-bj/bj-4a4336afc385d4b32b3ea1490dab311502763771)]

与bloom filter 异同点:

  • 同:大家都是用多个hash函数计算
  • 异:
    • bloom filter 作用在一个大空间内部,只能判断true OR False, 对于带频率的计算不准确。
    • Count-Min Sketch 分成多个子空间进行计算,由于由多路hash保证,最终计算的结果准确率相对较高,并且可以计算。
PK 机制
  • Rest 衰减 :对于所有key的访问频率之和有个最大值,当达到最大值时,会进行reset即对各个缓存key的频率除以2
  • 三阶段:通过对访问队列分成三段,这样避免了新加入的热点数据早早地被淘汰掉。

在这里插入图片描述

读写性能

在caffeine中认为缓存读比写多很多,所以对于写操作是所有线程共享一个Ringbuffer。

读完把数据放到环形队列 RingBuffer 中,为了减少读并发,采用多个 RingBuffer,每个线程都有对应的 RingBuffer。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4nyHvgJ-1632024843956)(http://bos.bj.bce-internal.sdns.baidu.com/agroup-bos-bj/bj-449a05427d35c32a9c77e95d790622d1449045fc)]

与读缓冲类似,写缓冲是为了储存写事件。读缓冲中的事件主要是为了优化驱逐策略的命中率,因此读缓冲中的事件完整程度允许一定程度的有损。但是写缓冲并不允许数据的丢失,因此其必须实现为一个安全的队列。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|

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敦兮其若朴,旷兮其若谷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值