周志明的软件架构课
周志明
博士,远光软件研究院院长,《深入理解 Java 虚拟机》《凤凰架构》等书作者
54203 人已学习
免费领取
课程目录
已完结/共 74 讲
架构师的视角 (24讲)
周志明的软件架构课
15
15
1.0x
00:00/00:00
登录|注册

21 | 服务端缓存的三种属性

你好,我是周志明。
在透明多级分流系统这个小章节中,我们的研究思路是以流量从客户端中发出开始,以流量到达服务器集群中真正处理业务的节点作为结束,一起探索了在这个过程中与业务无关的一些通用组件,包括 DNS、CDN、客户端缓存,等等。
实际上,服务端缓存也是一种通用的技术组件,它主要用于减少多个客户端相同的资源请求,缓解或降低服务器的负载压力。所以,说它是一种分流手段也是很合理的。
另外,我们其实很难界定服务端缓存到底算不算与业务逻辑无关,因为服务端缓存通常是在代码中被显式调用的,这就很难说它是“透明分流”了。但是,服务端缓存作为流量到达服务端实际处理逻辑之前的最后一道防御线,把它作为这个小章节的最后一讲,倒也是合适的。
所以这节课,我就带你来了解下服务端缓存的相关知识点,你可以从中理解和掌握缓存的三种常见属性,然后灵活运用在自己的软件开发当中。
好,接下来,我们就从引入缓存的价值开始学起吧。

为系统引入缓存的理由

关于服务端缓存,首先你需要明确的问题是,在为你的系统引入缓存之前,它是否真的需要缓存呢?
我们很多人可能都会有意无意地,把硬件里那种常用于区分不同产品档次、“多多益善”的缓存(如 CPU L1/2/3 缓存、磁盘缓存,等等)代入到软件开发中去。但实际上,这两者的差别是很大的。毕竟,服务端缓存是程序的一部分,而硬件缓存是一种硬件对软件运行效率的优化手段。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了服务端缓存的关键属性,包括吞吐量和命中率。首先,文章强调了吞吐量在并发场景中的重要性,并介绍了不同缓存容器的性能差异。特别是针对Caffeine缓存的设计方法,通过异步日志提交机制和环形缓冲的应用,有效避免了数据竞争,提高了读取性能。其次,文章详细讨论了缓存的命中率,强调了命中率对缓存价值的衡量,以及不同缓存方案的权衡问题。通过对Guava Cache和Caffeine的比较,阐述了同步处理机制和异步日志提交机制对命中率的影响。文章还介绍了缓存的淘汰策略,包括FIFO、LRU和LFU,以及改进版本TinyLFU和W-TinyLFU的工作原理和优化效果。这些淘汰策略的选择直接影响缓存的命中率,而近年出现的高级淘汰策略在搜索场景中表现接近于理想曲线。整体而言,本文为读者提供了全面了解服务端缓存技术的机会,使其能够更好地应用于实际软件开发中,提高系统性能和效率。

该试读文章来自《周志明的软件架构课》,如需阅读全部文章,
请先领取课程
免费领取
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • Jxin
    1.下来得自己研究下coff那个环形缓冲了,没看明白。至于lru分段这个mysql的缓存也有用到,好处能够理解。 2.提一嘴,应该是写错了。多线程操作cMap不一定会有锁竞争,不管是1.8之后还是之前。其核心思想分治,本就是错开操作降低竞争概率。 3.软件开发两大难题之一,缓存失效(另一个是命名)。其带来的风险: 1.该失效时未失效,导致数据错误。 2.不该失效时失效,出现击穿,进而可能引发雪崩。

    作者回复: 关于1,我看了一下,应该是编辑把我给的GIF图片弄成静态的了,囧。不然我觉得看图就能懂,原图的位置在,编辑同学看到了也请更新一下:https://icyfenix.cn/architect-perspective/general-architecture/diversion-system/cache-middleware.html 关于2,我搜索了一下,原文中没有提到“多线程操作ConcurrentHashMap一定会有锁竞争”的意思。我猜测你应该是指这里:“或者改用ConcurrentHashMap来实现,这相当于给Map的访问分段加锁(从JDK 8起已取消分段加锁,改为CAS+Synchronized锁单个元素)” ConcurrentHashMap(JDK8)中读操作完全没有线程安全措施,无论是CAS还是Synchronized都没有做。写操作是通过CAS来做节点位置判断,通过Synchronized来修改值。单个值级别的锁定意味着只有不同线程、修改同一个值才会有锁竞争。不同线程修改不同的值不会竞争相同的锁,或者相同线程修改同一个值锁是可重入的,简而言之“有锁”并不一定是指“有竞争”。 关于3,“另一个是命名”逗笑了。

    2021-01-04
    6
    22
  • 不在低谷拂袖去
    而写入数据的同时,也会伴随着数据状态的读取操作 周老师,这里能举例说一下吗?

    作者回复: 譬如写数据时,需要读取(以及更新)数据的超时时间、命中率等统计数据。这些状态,不仅对缓存使用者有用,对缓存本身如何存储数据也有着密切的关系。

    2021-01-21
  • hqx
    这些缓存更多是单机的应用,老师能否也介绍下分布式的缓存呀。

    作者回复: 后面一节课就介绍了

    2021-01-05
  • Scott
    我也读过Caffeine的代码,读不明白的地方还写邮件去问作者,作者为人过于nice,一直非常耐心的解答,还给出各种资源,还主动提示,里面他最得意的代码是TimeWheel。
    2021-05-03
    18
  • 草原上的奔跑
    1.数据不一致 2.增加系统架构的复杂性 2.缓存失效后(如缓存雪崩),对后端服务或数据库产生冲击
    2021-01-04
    7
  • neohope
    1、增加了整个系统的复杂度,增加了系统的故障点,系统的整体可靠性可能会下降。比如Redis遇到bigkey,处理不好会让系统性能明显下降;如果Redis所在服务器CPU或内存资源不足,也会引起严重的性能问题 2、增加缓存后,缓存的预加载、过期失效、击穿、穿透、雪崩等问题,需要付出额外代价去解决 3、增加缓存后,缓存与数据库数据的一致性是个难题,需要付出额外代价去解决 4、分布式环境下,各缓存之间的数据同步及一致性,也是个难题,需要付出额外代价去解决 5、分布式环境下,缓存的高可用及冷启动后快速恢复,需要付出额外代价去解决
    2021-04-02
    3
  • shark
    缓存可能存在什么风险弊端? 1,缓存数据与源数据的一致性(如与数据库不一致等) 2,开发过程中需要程序员操作缓存,要求程序员正确使用 3,缓存数据线上排查问题比较麻烦,进程内缓存无法探查缓存内容
    2021-06-13
    2
  • zhanyd
    缓存可能存在什么风险弊端? 1.增加代码复杂度,运维的难度。 2.淘汰策略选择不当,或者缓存数据设置不当,导致命中率太低,反而会增加CPU和I/O的压力,使系统响应速度更慢。 3.随着业务的变化,可能需要频繁地调整需要缓存的数据,可能会违背开闭原则:“对扩展开放,对修改关闭”(不知道对不对?)。
    2021-01-04
    1
  • hillwater
    本地缓存还存在另一个风险:深拷贝问题。guava默认是无拷贝的,存入缓存的对象继续操作,导致缓存的数据也同时被修改了。这样导致的bug很难排查。一般推荐进入缓存的对象不允许继续操作,或者进行深拷贝
    2023-08-17归属地:上海
  • Andrew陈海越
    缓存是有状态的数据,可以通过同步和异步日志两种策略来维护。 RingBuffer的用处。 缓存相关的考虑,吞吐量,命中率,管理监控,分布式。 各种缓存淘汰策略的权衡
    2022-10-14归属地:湖南
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部