系统设计面试的 9 个缓存策略
披露:本篇文章包含附属链接;如果您通过本文提供的不同链接购买产品或服务,我可能会收到报酬。
图片来源 - ByteByteGo
大家好,在系统设计中,效率和速度至关重要。为了提升性能并缩短响应时间,缓存起着至关重要的作用。如果您不知道什么是缓存?我先简单介绍一下。
缓存是一种将经常访问的数据的副本存储在可以更快检索的位置的技术。
例如,您可以在 CDN(内容分发网络)中缓存网站访问量最大的页面,或者类似地,交易引擎可以在处理订单时缓存符号表。
过去,我分享过几篇系统设计面试文章,例如API 网关与负载均衡器、正向代理与反向代理以及常见的系统设计问题,在本文中,我们将探讨系统设计中缓存的基础知识,并深入研究技术面试必备知识的不同缓存策略。
这也是程序员必须了解的系统设计主题或概念之一。
顺便说一句,如果你正在准备系统设计面试,并且想要深入学习系统设计,那么你也可以查看ByteByteGo、Design Guru、Exponent、Educative和Udemy等网站,它们有很多很棒的系统设计课程
PS:请坚持读到最后。我有一个免费赠品给你。
软件设计中的缓存是什么?
从本质上讲,缓存是一种将数据副本存储在可以比原始源更快访问的位置的机制。
通过保持经常访问的信息随时可用,系统可以更快地响应用户请求,从而提高整体性能和用户体验。
在系统设计中,缓存可以发生在各个级别,包括:
-
客户端缓存
客户端(用户的设备)在本地存储资源的副本,例如图像或脚本,以减少对服务器重复请求的需要。 -
服务器端缓存
服务器存储对请求的响应的副本,以便如果再次发出相同的请求,它可以快速提供相同的响应。 -
数据库缓存
经常查询的数据库结果存储在内存中以便更快地检索,从而减少了重复执行相同数据库查询的需要。
下图显示了客户端和服务器端缓存:
系统设计面试的 9 个缓存策略
了解不同的缓存策略对于顺利通过技术面试至关重要,尤其是对于涉及设计可扩展且高性能系统的职位而言。以下是一些需要了解的关键缓存策略:
1.最近最少使用(LRU)
这种类型的缓存用于优先移除最近最少使用的项目。你可以通过跟踪每个项目的使用情况并移除最长时间未使用的缓存来轻松实现这种缓存。
如果面试时被问到,可以使用双向链表来实现这种缓存,如下图所示。
不过,在现实世界中您不需要创建自己的缓存,您可以使用现有的数据结构(如 Java 中的 ConcurrentHashMap)进行缓存,或使用其他开源缓存解决方案(如 EhCache)。
2.最近使用(MRU)
在这种类型的缓存中,最近使用的缓存项会被优先移除。与 LRU 缓存类似,它需要跟踪每个缓存项的使用情况,并逐出最近使用的缓存项。
3.先进先出(FIFO)
这种类型的缓存会优先清除最旧的缓存项。如果在面试时被问到,你可以使用队列数据结构来维护缓存项的添加顺序。
4. 随机替换
这种类型的缓存会随机选择一个项目进行驱逐。虽然这种类型的缓存实现起来更简单,但可能并非在所有场景下都是最佳的。
5. 直写缓存
在这种类型的缓存中,数据同时写入缓存和底层存储。这种缓存的优点之一是它能够确保缓存始终保持最新。
另一方面,由于双重写入,写入延迟会增加。
6. 后写式缓存(Write-Back)
在这种类型的缓存中,数据会立即写入缓存,而对底层存储的更新则会被推迟。
这也减少了写入延迟,但如果系统在更新写入存储之前发生故障,则会增加数据丢失的风险。
它的工作原理如下:
7. Cache-Aside(延迟加载)
这意味着应用程序代码负责将数据加载到缓存中。它控制着哪些数据需要缓存,但另一方面,它也需要额外的逻辑来管理缓存的填充。
缓存失效
除了缓存和不同的缓存策略之外,这是软件工程师应该了解的另一个重要概念。
当底层存储中的相应数据发生变化时,缓存失效会删除或更新缓存条目。
缓存失效的最大好处是确保缓存数据保持准确,但同时也带来了管理缓存一致性的复杂性。
这里有一张来自DeisgnGuru.io的图表,解释了系统设计面试中各种缓存失效策略
全局缓存与本地缓存
在全局缓存中,单个缓存由多个实例共享。在本地缓存中,每个实例都有自己的缓存。全局缓存的优势之一是它可以提高数据一致性,而本地缓存可以减少争用并提高性能。
系统设计面试资源:
这里精选了一些最佳系统设计书籍、在线课程和练习网站,您可以参考这些内容,更好地准备系统设计面试。这些课程中的大多数也解答了我在这里分享的问题。
-
DesignGuru 的 Grokking 系统设计课程:一个交互式学习平台,通过实践练习和真实场景来加强您的系统设计技能。
-
Alex Xu 撰写的《系统设计面试》:本书深入探讨了系统设计的概念、策略和面试准备技巧。
-
Martin Kleppmann 撰写的《设计数据密集型应用程序》:一本涵盖设计可扩展且可靠系统的原则和实践的综合指南。
-
LeetCode 系统设计标签:LeetCode 是一个流行的技术面试准备平台。LeetCode 上的系统设计标签包含各种练习题。
-
GitHub 上的“系统设计入门”:精选资源列表,包括文章、书籍和视频,可帮助您准备系统设计面试。
-
Educative 的系统设计课程:一个交互式学习平台,通过实践练习和真实场景来加强您的系统设计技能。
-
高可扩展性博客:一个以高流量网站和可扩展系统架构的文章和案例研究为特色的博客。
-
YouTube 频道:查看“Gaurav Sen”和“Tech Dummies”等频道,获取有关系统设计概念和面试准备的深刻视频。
-
ByteByteGo:Alex Xu 编写的一本用于系统设计面试准备的在线书籍和课程。它包含《系统设计面试》第一卷和第二卷的所有内容,并将于即将更新第三卷。
-
Exponent:一个专门为亚马逊和谷歌等 FAANG 公司提供面试准备的专业网站,他们还提供很棒的系统设计课程和许多其他材料,可以帮助您破解 FAANG 面试。
图片来源 - ByteByteGo
结论:
这就是软件工程师应该了解的关于缓存以及不同类型的缓存的全部内容。正如我所说,缓存是系统设计中的一个基本概念,对缓存策略的透彻理解对于技术面试的成功至关重要。
无论您是优化速度、最小化延迟还是确保数据一致性,选择正确的缓存策略都取决于您正在设计的系统的具体要求。
在准备技术面试时,深入研究这些缓存策略,了解它们的权衡,并准备将这些知识应用到实际场景中。
福利:
正如承诺的那样,这是给你的福利,一本免费的书。我刚刚找到了一本学习分布式系统设计的免费新书,你也可以在微软官网上阅读——https: //info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT-eBook-DesigningDistributedSystems.pdf