[译]通过超市买牛奶来学习缓存

1,133 阅读7分钟

如果你去超市买过牛奶,那你就能理解服务端和客户端缓存!

如果你是一个互联网用户,那你一直受益于缓存!但是,你可能不知道它何时以何种形式发挥作用。

从开发人员的角度看,缓存是构建高性能应用和服务的必要手段。通过实现缓存,开发者能更好地处理海量请求。也许缓存优化的效果只有 1 ~ 2s 的区别,差异微乎其微。但如果你想要处理海量用户的请求,这是必要的!

我曾经做过一个网络应用程序,使我对缓存的理解更加深刻。仅通过专业术语可能很难明白缓存的含义,所以本文我将通过牛奶的生产线来帮助理解缓存的概念。在理解本文之前,你需要了解 web 服务器。不懂的童鞋可以通过链接了解。

没有缓存,互联网会是什么样?

在我们聊缓存之前,想象一下没有缓存的互联网会是什么样的?假如你生活在18或19世纪的农村,你拥有一个农场——没有冷藏技术。农场里有几头奶牛,产出的牛奶会因为变质而变得没有价值。(补充一下:有趣的是有些地方现在仍然没有冷藏技术,他们直接喝牛乳,或者伴着谷物发酵后再喝。)

你要将牛奶卖给同乡的小伙伴,会面临三个问题:

  • 喝牛奶的时间非常有限。
  • 如果同时有很多人都需要牛奶,由于奶牛产量有限(假设一头奶牛每天能产出一加仑牛奶),你只能让他们先回家,隔天再来。

  • 通过增加奶牛来扩大生产量。因为只有同村人能购买牛奶,所以产量溢出时会造成浪费。

没有缓存,你将受限于服务的计算能力。缓存被用来加载静态资源,例如:

  • 图片
  • css
  • 静态 HTML 文件
  • JavaScript 文件

默认情况下,服务器必须为每个传入请求返回响应。但是加载页面的请求通常包含上述四种资源。当你加载大图时,服务器将不堪重负。导致用户需要等待漫长的加载时间。

理想情况下,你希望通过存储常见请求的响应来减轻服务器的压力。通过缓存,服务器不需要处理每一个新的请求就能快速响应。当然,你也可以随时购买更多的服务器去分解请求压力,但这成本非常高。

什么是服务端缓存?

回到农场场景,我们怎样才能更容易地经营好奶牛场呢?答案是拥有一家带有冷藏技术的超市!如此一来人们就不需要亲自到奶牛场去喝牛奶。你也可以将牛奶安全地存放一段时间。

超市缓解了农场压力。因为奶牛不会实时生产,超市能够解决实时的问题。你要做的就是保持奶牛每天的产量!更好的是,周围村庄的居民随时都可以在超市购买到新鲜牛奶。

就像超市一样,服务器端缓存可以处理高并发的请求,并更快速,更可靠地提供内容。上图中,有一个术语是缓存代理——一种服务器,用于存储常见的请求响应。缓存代理将拦截常见请求并快速传递响应。它可以防止这些请求对主 Web 服务器造成压力。

看了上文,你可能有一堆问题,比如:

  • 什么是高并发?
  • 缓存代理能响应多长时间?

回答上面问题可能需要很长的一篇文章,现在,你需要了解“新鲜度”的概念。缓存代理在不同时间缓存不同的文件,并且需要决定是否继续缓存某些文件。这些问题的答案取决于缓存策略。

这也像超市里的牛奶一样,超市经理需要在牛奶保质期过后将牛奶丢弃。缓存代理通过缓存命中率(可通过缓存服务器提供的内容的百分比)来衡量其成功率。

什么是 CDN?

到目前为止,你已经有了一家商店,相比以前这是很大的进步。但是如果你想把牛奶卖给更远的人,就需要开更多的门店。

开了更多更远的门店,你就能把牛奶分配到这些门店销售。从而满足更多人群的需求。这就类似于 CDN —— 位于世界各地的一系列服务器。

作为用户,你使用大多数网站的感觉都是非常快速的,原因之一就是使用了 CDN 来加速静态文件的加载。

如果你在英格兰尝试加载缓存在弗吉尼亚州服务器中的文件,将有一些延迟,因为原始信号只能沿着数千英里的电缆传输。本地缓存代理将会使网站加载得更快。

服务器可以将静态资源的副本发送到 CDN 网络中的每个代理服务器,并且它们可以处理本地请求,直到资源过期。一些常见的 CDN 提供商包括 Rackspace , Akamai 和 Amazon Web Services 。

浏览器缓存

有了商店,全世界的人都可以快速地购买农场牛奶。但是购买之后他们还是要快速地喝完,因为无法储存在自己家里。怎么解决呢?非常简单,在家里放一个冰箱呗。

有了冰箱,你可以将牛奶储存在家里而不用送回超市。回到缓存方面,指的是存储静态资源的本地位置——客户端,而代理服务器位于远端位置。

值得注意的是,牛奶不会自动神奇地送到冰箱。需要你从超市购买回家,然后放入冰箱。所以首次请求还是必要的,之后就可以将其缓存在本地。

浏览器怎么知道何时从服务器请求新资源呢?解决不了这个问题,你将无法更新本地文件的版本。

就好比每瓶牛奶都有保质期,服务器在 HTTP 响应头部添加某种标识符。实际上有4个独立的 HTTP 缓存系统。上述场景就类似“保质期”的方法,要求浏览器在发送文件之前需要检查服务器。

何时开始使用缓存?

假设你正在开发一个 app。如果只有几千个用户,你不需要担心缓存问题,因为服务器消耗比较低。然而当应用扩张时,还想继续保持 app 速度和效率,那么就需要实现缓存。

例如,(Heroku)[zh.wikipedia.org/zh-sg/Herok…] 是部署 Web 应用程序的绝佳工具。但是,它要求使用单独的服务器实现缓存,例如亚马逊的 CloudFront 或 CloudFlare 。这需要更多时间来学习这些工具的使用。

在浏览器端,当你尝试使用新的静态资源重新加载页面时,会由于资源已经缓存到本地,所以页面根本不会更改。无论刷新页面多少次,都没有任何变化。

这通常是因为浏览器端的一些缓存协议。要绕过浏览器的缓存并从服务器请求新资源,你可以在 Mac 上使用 Cmd + Shift + R 或在 Window 上使用 Ctrl + Shift + R

原文链接