聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

中有很多的开源框架都有提供类似的能力支持,比如或者、等,可以通过简单的添加注解的方式就实现上述需要的缓存效果。比如使用Ehcache来实现接口接口缓存的时候,代码使用方式如下(这里先简单的演示下,后续的系列文档中会专门对这些框架进行深入的探讨):

基上面的本地缓存策略改动后重新上线,整体的响应性能上果然提升了很多。本地缓存的策略虽然有效地提升了处理请求的速度,但新的问题也随之浮现。有用户反馈,社区内的帖子列表多次刷新后会出现内容不一致的情况,有的帖子刷新之后会从列表消失,多次刷新后偶尔会出现。

其实这就是本地缓存在集群多节点场景下会遇到的一个很常见的缓存漂移现象:

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

业界成熟的集中式缓存有很多,最出名的莫过于很多人都耳熟能详的,或者是在各种面试中常常被拿来与Redis进行比较的。也正是由于它们出色的自身性能表现,在当前的各种分布式系统中,Redis近乎已经成为了一种标配,常常与等持久化数据库搭配使用,放在数据库前面进行扛压。比如下面图中示例的一种最简化版本的组网架构:

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

上图演示的也即多级缓存的策略。具体而言:

  • 对于一些变更频率比较高的数据,采用,这样可以确保数据变更之后所有节点都可以实时感知到,确保数据一致;

  • 对于一些极少变更的数据(比如一些系统配置项)或者是一些对短期一致性要求不高的数据(比如用户昵称、签名等)则采用,大大减少对远端集中式缓存的网络IO次数。

这样一来,系统的响应性能又得到了进一步的提升。

通过对缓存使用策略的一步步演进,我们可以感受到缓存的恰当使用对系统性能的帮助作用。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

编码源于生活,的高速缓存设计就是这一生活实践在计算机领域的原样复制。缓存可以说在软件世界里无处不在,除了我们自己的业务系统外,在、、、中都可以看到缓存的影子。如:

  1. 网络传输场景

比如,基于ARP缓存表进行与终端硬件地址之间的缓存映射。这样与对端主机之间有通信需求的时候,就可以在ARP缓存中查找到IP对应的对端设备MAC地址,避免每次请求都需要去发送ARP请求查询MAC地址。

  1. MyBatis的多级缓存

作为体系中被广泛使用的数据库操作框架,其内部为了提升处理效率,构建了一级缓存二级缓存,大大减少了对的重复执行次数。

  1. CPU中的缓存

与之间有个临时存储器(高速缓存),容量虽比内存小,但是处理速度却远快于普通内存。高速缓存的机制,有效地解决了与不匹配的问题。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活
  • 对一些中间处理结果进行存储

比如系统中的数据报表模块,需要对整个系统内所有的关联业务数据进行计算统计,且需要多张表多来源数据之间的综合汇总之后才能得到最终的结果,整个过程的计算非常的耗时。如果借助缓存,则可以将一些中间计算结果进行暂存,然后报表请求中基于中间结果进行二次简单处理即可。这样可以大大降低基于请求触发的实时计算量。

在“”实施策略中,缓存是该策略的核心、也是被使用的最为广泛的一种方案。借助缓存,可以将一些耗时计算的处理结果进行缓存复用,以降低重复计算工作量,达到降低占用的效果。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

除了上述的因素之外,对一些移动端或者界面而言,缓存的使用还有一个层面的考虑,即降低用户的流量消耗,通过将一些资源类数据缓存到本地,避免反复去下载,给用户省点流量,也可以提升用户的使用体验(界面渲染速度快,减少出现白屏等待的情况)。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活
  • 记住一些用户上次,比如用户在一个页面上将列表分页查询设置为条/页,则后续在系统内访问其它列表页面时,都沿用这一设置。

  • 缓存用户的一些,这个主要是端常用的功能,可以在缓存中保存些与当前设备绑定的设置信息,仅对当前设备有效。比如同一个账号登录某个APP,用户希望在手机端可以显示深色主题,而PAD端则显示浅色主体,这种基于设备的个性化设置,可以缓存到设备本身即可。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

由于业务模块自行实现缓存与数据库之间的数据写入与更新的逻辑,实际实现的时候需要注意下在高并发场景的问题,以及可能会出现的、、等问题的防护。

旁路型缓存是实际业务中最常使用的一种架构模式,在后面的内容中,我们还会不断的涉及到旁路缓存中相关的内容。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

这种模式对业务而言是比较友好的,业务只需调用缓存接口即可,无需自行实现缓存与DB之间的交互策略。

异步型缓存

还有一种缓存的使用模式,可以看作是穿透型缓存的演进异化版本,其使用场景也相对较少,即异步型缓存。其主要策略就是业务侧请求的实时读写交互都是基于缓存进行,任何数据的读写也完全基于缓存进行操作。此外,单独实现一个数据持久化操作(独立线程或者进程中执行),用于将缓存中变更的数据写入到数据库中。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

同样地,我们也可以去放心的清理的缓存,而不用担心清理之后我们浏览器或者网页的功能会出现异常(最多就是需要重新下载或者重建缓存数据,速度会有一些慢)。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

有兜底屏障

缓存作为高并发类系统中的核心组件,负责抗住大部分的并发请求,一旦缓存组件出问题,往往对整个系统会造成毁灭性的打击。所以我们的缓存在实现的时候必须要有充足且完备的兜底自恢复机制。需要做到以下几点:

  • 关注下缓存数据量超出承受范围的处理策略,比如定好数据的。

  • 避免缓存集中失效,比如批量加载数据到缓存的时候过期时间,避免同一时间大批量缓存失效引发缓存雪崩问题。

  • 有效地冷数据预热加载机制,以及热点数据防过期机制,避免出现大量对冷数据的请求无法命中缓存或者热点数据突然失效,导致问题。

  • 合理的防身自保手段,比如采用机制,避免被恶意请求攻陷,导致缓存穿透类的问题。

缓存的可靠性与兜底策略设计,是一个宏大且宽泛的命题,在本系列专栏后续的文章中,我们会逐个深入的探讨。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

上图的数据更新处理策略,可以有效地保证数据的最终一致性,降低极端情况可能出现数据不一致的概率,并兜底增加了数据不一致时的自恢复能力。

数据一致性保证作为缓存的另一个重要命题,我们会在本系列专栏后续的文章中专门进行深入的剖析。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

为了能够将缓存的方方面面彻底的讲透、讲全,在接下来的一段时间里,我会以系列专栏的形式,从不同的角度对缓存的方方面面进行探讨。不仅仅着眼于如何去使用缓存、也一起聊聊缓存设计中的一些 —— 这一点是我觉得更有价值的一点,因为这些理念对提升我们的软件架构认知、完善我们的软件设计思维有很大的指导与借鉴意义。

所以,如果你有兴趣,欢迎关注本系列专栏(深入理解缓存原理与实战设计),我会以我一贯的行文风格,用最简单的语言讲透复杂的逻辑,期待一起切磋、共同成长。

聊一聊作为高并发系统基石之一的缓存,会用很简单,用好才是技术活

我是悟道,聊技术、又不仅仅聊技术~

如果觉得有用,请点赞 + 关注让我感受到您的支持。也可以关注下我,全网同名,获取更及时的更新。

期待与你一起探讨,一起成长为更好的自己。

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树并发并发的定义91318 人正在系统学习中

来源:架构悟道

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年9月22日
下一篇 2022年9月22日

相关推荐