大家好,缓存不仅是系统设计面试的重要主题,它也是软件开发中的技术,可以加快数据检索速度,减少加载时间并增强用户体验。
对于开发人员来说,掌握缓存概念至关重要,因为它可以显著优化应用程序的性能和可扩展性。
过去,我讨论过常见的系统设计问题,例如API 网关与负载均衡器、水平扩展与垂直扩展、正向代理与反向代理以及常见的系统设计问题,在本文中,我们将探讨系统设计中缓存的基础知识,并学习技术面试必备知识的不同缓存策略。
这也是面试中必不可少的系统设计主题之一,你必须做好准备。
在本文中,您将学习十个基本的缓存概念,从客户端和服务器端策略到更高级的技术,如分布式缓存和缓存替换策略
那我们还等什么?开始吧
顺便说一句,如果你正在准备系统设计面试,并且想要深入学习系统设计,那么你也可以查看ByteByteGo、Design Guru、Exponent、Educative、Codeemia.io和Udemy等网站,这些网站有许多很棒的系统设计课程和像这样的系统设计面试模板,你可以使用它来回答任何系统设计问题。
如果您需要更多选择,您还可以查看最佳系统设计课程、书籍和网站的列表
PS:请继续阅读到最后。我有一个免费赠品给你。
什么是缓存?缓存哪些数据?缓存在哪里?
在设计分布式系统时,应策略性地放置缓存以优化性能,减少延迟并最大限度地减少后端服务的负载。
缓存可以在多个层次上实现,例如
客户端缓存
这涉及将经常访问的数据存储在客户端设备上,从而减少对服务器的重复请求。它对于不经常更改的数据很有效,并且可以通过减少延迟来显著改善用户体验。边缘缓存(内容分发网络 - CDN)
CDN 在最靠近最终用户的边缘节点缓存内容,这有助于通过从地理分布的服务器提供服务来更快地交付图像、视频和样式表等静态内容。应用程序级缓存
这包括应用程序层内的内存缓存,例如 Redis 或 Memcached。这些缓存存储昂贵的数据库查询结果、会话数据和其他经常访问的数据,以减少数据库负载并缩短应用程序响应时间。数据库缓存
数据库层中的查询缓存等技术可存储频繁查询的结果。这可减少对数据库的读取操作次数并加快数据检索速度。分布式缓存
在分布式系统中,分布式缓存跨越多个节点,以提供高可用性和可扩展性。它确保缓存的数据在分布式环境中保持一致,并能处理大型系统所需的高吞吐量。
在设计缓存策略时,通过分析使用模式、数据波动性和访问频率来确定要缓存哪些数据至关重要。
实施适当的缓存驱逐策略(例如 LRU - 最近最少使用,或 TTL - 生存时间)可确保清除陈旧数据,从而保持缓存的相关性。
此外,考虑一致性模型和缓存失效策略对于确保缓存数据在整个系统中保持准确和最新至关重要。
这里有一张来自DesignGuru.io的关于缓存的图表,可以说明我刚才所说的内容。
系统设计面试中的 10 个缓存基础知识
以下是每个程序员在参加任何系统设计面试之前必须了解的 10 个基本缓存相关的基础知识和概念。
1)客户端缓存
客户端缓存是一种基本技术,将数据存储在用户设备上,以最大限度地减少服务器请求并缩短加载时间。两种主要方法包括:
浏览器缓存: 在本地存储 CSS、JavaScript 和图像等资源,以减少后续访问的页面加载时间。
服务工作者: 通过缓存响应实现离线访问,使应用程序无需互联网连接即可运行。
简而言之:
浏览器缓存:存储 CSS、js、图像以减少加载时间
服务工作者:通过缓存响应实现离线访问
客户端缓存如下所示:
2)服务器端缓存
这是另一种类型的缓存,涉及在服务器上存储数据以加快用户请求的响应时间。
关键策略包括:
页面缓存: 保存整个网页,以便更快地处理后续请求。
片段缓存:
缓存页面的特定部分,例如侧边栏或导航栏,以提高加载效率。对象缓存:
存储昂贵的查询结果,以防止重复计算
简而言之:
页面缓存:缓存整个网页
片段缓存:缓存页面组件,如侧边栏、导航栏
对象缓存:缓存昂贵的查询结果
服务器端缓存如下所示:
图片来源 --- ByteByteGo
3)数据库缓存
数据库缓存对于减少数据库负载和提高查询性能至关重要。重要的技术包括:
查询缓存:
存储数据库查询的结果以快速满足重复请求。行级缓存:
缓存经常访问的行以避免重复获取数据库。
简而言之:
查询缓存:缓存数据库查询结果以减少负载
行级缓存:缓存常用行以避免重复获取
以下是 AWS 上数据库缓存的一个示例:
4)应用程序级缓存
应用程序级缓存侧重于应用程序内的缓存,以减少计算和数据检索时间。策略包括:
数据缓存:存储特定数据点或整个数据集以便快速访问。
计算缓存:缓存昂贵的计算结果以避免重复处理。
简而言之:
数据缓存:缓存特定数据点或整个数据集
计算缓存:缓存昂贵的计算结果以避免重新计算
5)分布式缓存
分布式缓存通过将缓存数据分布在多台服务器上来增强可扩展性,从而实现高可用性和容错能力。
简而言之,这种类型的缓存只是将缓存分散到许多服务器上以实现可扩展性
使用 Redis 的分布式缓存如下所示:
6)CDN
内容分发网络 (CDN)用于通过边缘服务器缓存靠近用户的静态文件,从而显著减少延迟并加快内容分发速度。
简而言之,CDN 使用边缘服务器将静态文件存储在用户附近,以降低延迟
另外,这里有一张由 DeisgnGuru.io 提供的 CDN 工作原理图
7)缓存替换策略
缓存替换策略决定了缓存如何处理数据驱逐。常见的策略包括:
最近最少使用 (LRU):首先驱逐最近最少访问的项目。
最近使用(MRU):首先驱逐最近访问的项目。
最不频繁使用 (LFU):逐出访问次数最少的项目。
简而言之:
- LRU: removes the least recently accessed items first\
- MRU: removes the most recently accessed items first\
- LFU: removes items that are accessed least often
8)分层缓存
分级缓存涉及多个缓存级别(例如 L1、L2),以平衡速度和存储容量。这种模型在 CPU 上非常流行。
简而言之:
多层缓存(L1、L2 缓存)以提高速度和容量
9)缓存失效
缓存失效可确保从缓存中删除过时的数据。方法包括:
生存时间 (TTL):设置缓存数据的到期时间。
基于事件的无效:根据特定事件或条件触发无效。
手动失效:允许开发人员使用工具手动更新缓存。
简而言之:
- TTL: set expiry time\
- event based: invalidate based on events or conditions\
- manual: update cache using tools
为了更好地理解这个概念,这里有一个由DesignGuru.io提供的关于缓存失效方法的系统设计备忘单:
10)缓存模式
最后,缓存模式是将缓存与数据库同步的策略。常见模式包括:
直写:将数据同时写入缓存和数据库。
后写:立即将数据写入缓存并异步写入数据库。
绕写:直接将数据写入数据库,绕过缓存,以避免后续读取时出现缓存未命中。
简而言之:
- write-through: data is written to the cache and the database at once\
- write-behind: data is written to the cache and asynchronously to database\
- write-around: data is written directly to the database, bypassing the cache
这是另一个很好的图表,可以帮助您了解各种缓存策略,由DesignGuru.io提供,它是学习系统设计的最佳场所之一。
最佳系统设计面试资源
此外,这里还精选了最佳系统设计书籍、在线课程和练习网站,您可以查看这些内容以更好地准备系统设计面试。这些课程中的大多数也回答了我在这里分享的问题。
DesignGuru 的 Grokking 系统设计课程:一个交互式学习平台,通过实践练习和真实场景来加强您的系统设计技能。
Codeemia.io:这是另一个练习面试系统设计问题的绝佳平台。它有超过 120 个系统设计问题,其中许多都是免费的,并且有适当的结构来解决它们。
Alex Xu 撰写的《系统设计面试》:本书深入探讨了系统设计的概念、策略和面试准备技巧。
Martin Kleppmann 撰写的《设计数据密集型应用程序》:一本全面的指南,涵盖了设计可扩展且可靠系统的原则和实践。
LeetCode 系统设计标签:LeetCode 是一个流行的技术面试准备平台。LeetCode 上的系统设计标签包含各种练习问题。
GitHub 上的“系统设计入门”:精选的资源列表,包括文章、书籍和视频,可帮助您准备系统设计面试。
Educative 的系统设计课程:一个交互式学习平台,包含实践练习和真实场景,以加强您的系统设计技能。
高可扩展性博客:该博客提供有关高流量网站和可扩展系统架构的文章和案例研究。
YouTube 频道:查看“Gaurav Sen”和“Tech Dummies”等频道,获取有关系统设计概念和面试准备的精彩视频。
ByteByteGo:Alex Xu 撰写的一本用于系统设计面试准备的现场书籍和课程。它包含系统设计面试书籍第 1 卷和第 2 卷的所有内容,并将在即将推出的第 3 卷中更新。
Exponent:一个专门为亚马逊和谷歌等 FAANG 公司提供面试准备的网站,他们还有很棒的系统设计课程和许多其他材料,可以帮助您破解 FAAN 面试。
图片来源 - ByteByteGo
结论
以上就是系统设计面试中 10 个基本缓存相关概念的全部内容。缓存可以提高应用程序的性能和可扩展性。因此请谨慎使用。理解和实施这些缓存概念可以显著提高应用程序的性能、可扩展性和用户满意度。
您可能喜欢的其他系统设计文章和资源