目录
缓存
不同的缓存策略
1. 浏览器缓存
缓存命中和缓存未命中
2. 服务器缓存
缓存失效
驱逐策略:缓存的决策制定者
自适应策略
自定义策略
驱逐策略的影响
3. 数据库缓存
实施
它的工作原理
处理缓存未命中
理想应用场景:数据库缓存的优势
驱逐策略
更广泛的影响
4. 内容交付网络(CDN)
CDN的工作原理
CDN类型:推送 vs. 拉取
引导CDN行为
在CDN和原始服务器之间进行选择
总览
CDN优势
总体缓存优势
1*JfOWR6ECe92QhH_UTwulrg.png
假设一家公司将其网站托管在芬兰的Google Cloud数据中心的服务器上。对于欧洲的用户,加载可能需要大约100毫秒,但对于墨西哥的用户,可能需要3-5秒。幸运的是,有策略可以最小化远程用户的请求延迟。
1*y8FX7ipmMhkERbkuKVAjlA.png
这些策略被称为缓存和内容交付网络(CDN),它们是现代Web开发和系统设计中的两个重要概念。让我们深入了解它们:
缓存是一种用于提高系统性能和效率的技术。它涉及将某些数据的副本存储在临时存储区域(缓存)中,以便将来对该数据的请求可以更快地提供服务。
缓存数据可以极大地改善应用程序的性能。通常有4个常见的存储缓存数据的地方。
浏览器缓存涉及将网站资源存储在用户本地计算机上。当用户重新访问站点时,浏览器可以从本地缓存加载站点,而不是再次从服务器获取所有内容。
1*R3ZKI4nlTrOHDA-FhZBkbg.png
禁用浏览器缓存:用户可以通过调整浏览器设置来禁用缓存。在大多数浏览器中,开发人员可以在其开发者工具中找到网络设置,通常位于网络选项卡中。例如,您可以在Chrome的“开发者工具”>“网络”选项卡中使用“禁用缓存”选项。
存储位置:缓存存储在客户端硬盘上的目录中,由浏览器管理。浏览器缓存将HTML、CSS和JS捆绑文件存储在用户的本地计算机上,通常在浏览器管理的专用缓存目录中。
Cache-Control头:Cache-Control: max-age=3600
指令告诉浏览器将文件缓存3600秒(1小时)。
1*OqRgQkvPSMpEypUN3pGFtw.png
缓存命中发生在所请求的数据已经在缓存中的情况下。另一方面,缓存未命中发生在所请求的数据不在缓存中,需要从原始来源获取。
1*f2aOD9xR0ntFis-IYn4sRg.png
缓存比率是从缓存中提供服务的请求与所有请求相比的百分比。更高的比率表示缓存更有效。
您可以通过浏览器的开发者工具检查缓存在网络选项卡中指示的缓存状态,例如响应头中的X-Cache: Hit
表示缓存命中。
1*cofXwIshbBgnQ7nNAhhTSw.png
服务器缓存涉及在服务器上存储频繁访问的数据,减少对昂贵操作(如数据库查询)的需求。
1*5m7N3RGLHAZI5mKtN7nfxQ.png
位置:服务器端缓存存储在服务器本身或一个独立的缓存服务器上,可以是内存中的(如Redis)或磁盘上的。
过程:通常,在查询数据库之前,服务器会检查缓存以获取数据。如果数据在缓存中,它会直接返回。
但是,如果数据不在缓存中,服务器会从数据库检索数据,将其返回给用户,然后将其存储在缓存中以备将来的请求。
1*QBeoPkQXUeDp4HvTGtbDow.png
我们上面看到的过程是Write-Around缓存,其中数据直接写入永久存储,绕过缓存。这是在写性能不是很关键时使用的。
我们还有Write-Through缓存。这是在同时将数据写入缓存和永久存储的情况下。它确保数据一致性,但可能较慢。
1*CFWm06ExqvjRhtWiYvU4lg.png
另一种类型是Write-Back Cache。在这种情况下,数据首先写入缓存,然后在以后的某个时候写入永久存储。这提高了写性能,但在服务器或缓存服务器崩溃时存在数据丢失的风险。
选择取决于数据类型、访问模式和性能要求。
在缓存充满时,驱逐策略做出了有关从缓存中驱逐(或删除)哪些项目的关键决策。
让我们深入了解一些最常见的驱逐策略:
1.最近最少使用(LRU):想象一条线,最后一个到达的是第一个离开的。LRU基于这个原则运作。它跟踪使用历史并首先丢弃最近访问最少的项目。这就像一个优先考虑最新体验的记忆。2.先进先出(FIFO):FIFO是公平的典范——进入缓存的第一个项目是第一个退出的。这种方法不考虑数据的访问频率或最近性。就像一个有礼貌的队列,每个人都按顺序等候,而不考虑他们的重要性。3.最不经常使用(LFU):LFU就像一场流行度比赛。它跟踪项目的访问频率。访问最少的项目首先被淘汰。这种策略偏爱通过频繁请求证明其价值的项目。
1*04FrH7b3tVtT71RSgFtB9A.png
每种策略都有其优势和劣势,选择取决于系统的特定需求和行为。例如,LRU通常适用于最近访问的数据可能会再次需要的场景。另一方面,LFU对于访问模式不会迅速改变的情况很理想。
一些系统实施自适应策略,这些策略结合了这些基本策略的元素。这些更复杂的算法可以根据数据访问的演变模式调整其行为,确保在各种情况下实现最佳的缓存性能。
在某些情况下,特别复杂的系统可能需要定制的驱逐策略。这些策略专门针对系统的独特需求定制,可以考虑各种因素,如每个项目的大小、类型和检索每个项目的成本。
驱逐策略的选择可以显着影响缓存系统的性能。精心选择的策略确保缓存仅存储最有用的数据,从而减少延迟并提高响应时间。
数据库缓存是缓存策略领域的基石,对于大量依赖数据库交互的应用程序的性能提升起着关键作用。
1*YlTMBEoX-3E-X4ZOvkIEQw.png
数据库缓存可以通过两种主要方式实施:
1.内部缓存:这是数据库系统本身维护缓存。这类似于在数据库中内置了一个快速参考指南。2.外部缓存:在这种方法中,外部缓存(如Redis或Memcached)与数据库协同工作。可以将其视为具有记住频繁请求的专职助手。
当查询发送到系统时,数据库缓存就像一个门卫一样介入。它首先检查自己的内存,看看该查询的答案是否已知。如果结果存在于缓存中(缓存命中),它将直接返回,从而绕过了数据库重新处理查询的需要。
1*aphdXnyGN-GOyJZx6ydj_Q.png
缓存未命中类似于遇到了临时的路障。当缓存没有所需数据时,系统将执行针对数据库的查询。在检索所需信息后,它并不止于此——它将此结果存储在缓存中。这样,下次相同的查询敲门时,缓存已准备好了答案。
1*MI-0g6DTqU-H3OB33SYJJQ.png
数据库缓存在对读取操作较为频繁的应用中特别有益,即那些某些查询像是一再播放的流行曲。在这些场景中,缓存能够显著减少重新运行相同查询所花费的时间,从而提高整体性能。
与其他缓存系统类似,数据库缓存并非无限的存储池;它们也需要规则来决定留下什么、放弃什么。它们采用各种驱逐策略来有效管理内存使用,其中一种常见的策略是LRU(最近最少使用)。
实施有效的数据库缓存策略可以在应用的响应性和效率方面取得显著的改进。它减轻了对数据库的负载,加速了数据检索,并确保用户体验更为流畅。然而,像任何强大的工具一样,它需要谨慎的调整和管理。缓存方法的选择、缓存的大小以及驱逐策略都必须根据应用的特定需求进行校准,以实现最佳性能。
CDN是一组在地理位置上分布的服务器,通常用于提供静态内容,如JavaScript、HTML、CSS、图像和视频资产。它们缓存来自原始服务器的内容,并从最近的CDN服务器向用户交付。
1*IcZlU0SJbRcHPYZu8aBKsQ.png
内容交付网络(CDN)的过程如下:
1.初始请求:用户请求文件,可能是图像、视频或网页。2.最近服务器响应:该请求迅速重定向到最近的CDN服务器。3.内容交付:如果该服务器已经缓存了内容,它会直接交付给用户。4.检索和转发:在CDN服务器没有内容的情况下,它会从原始服务器检索内容,存储(缓存)然后发送给用户。这一步确保下次有人请求相同的内容时,它能够立即准备好。
1*Bw1AbgTtP7pCUwGiMWfw4Q.png
拉取式CDN:在这里,CDN起到积极的作用。它在第一次用户请求时从原始服务器拉取内容,非常适合具有定期更新的静态内容的站点。
1*0gmYG5mS4kDRBfAz2YA8ZA.png
推送式CDN:在这种情况下,你有控制权。你直接将内容上传到CDN。这种方法非常适合不经常更改但需要快速分发的大文件,类似于向快递服务发送包裹。
1*1rpkO4Cf6ctkgKc_tlf1BA.png
我们使用请求头来控制CDN的行为。
•Cache-Control: 这个头是CDN和浏览器缓存存储内容的规则书,包括max-age
、no-cache
、public
和private
等指令。•Expires: 这相当于内容的过期日期,标志着它何时变得陈旧。•Vary: 该头根据特定的请求头调整提供的内容,确保交付正确版本的内容。
选择CDN时:
•分发静态资产(图像、CSS、JavaScript)。•对各个地区的高可用性和性能至关重要。•卸载原始服务器是优先考虑的事项。
选择直接访问原始服务器时:
•内容是动态的、经常更改的或个性化的。•需要实时处理或新鲜数据。•涉及到无法由CDN处理的复杂服务器端逻辑。
总之,缓存和CDN对于增强Web性能、减少延迟以及确保通过互联网高流量、性能关键的Web应用的可扩展和高效交付内容方面至关重要。
•减少延迟: 通过从用户更近的位置提供内容,CDN显著减少延迟。•高可用性和可扩展性: CDN可以处理高流量负载,并且对硬件故障具有弹性。•提高安全性: 许多CDN提供DDoS防护和流量加密等安全功能。
•减少延迟: 由于数据是从附近的缓存而不是远程服务器检索的,因此数据检索速度更快。•降低服务器负载: 缓存减少对主数据源的请求次数,减少服务器负载。•改善用户体验: 更快的加载时间带来更好的用户体验。