菲尔Karlton曾经说过,“只有两种计算机科学坚硬的东西:缓存失效和命名的东西”这篇文章是关于这两个较硬的: 缓存失效 。 这是冲着谁的读者已经与光油缓存工作。 要了解更多关于它,你会发现背景信息在“ 加快你的手机网站清漆 。“
10微秒(或者250毫秒):这是提供一个高速缓存命中和提供一个高速缓存未命中之间的差异。 “命中率” – 你怎么经常得到后者将取决于缓存的效率,这是被称为缓存未命中取决于两个因素:交通量和平均生存时间(TTL),这是一个数字,指示缓存多长时间允许保留的对象。 作为系统管理员和开发人员, 我们不能做很多有关交通的,但我们可以影响的TTL。
然而,有一个高的TTL,我们需要能够从缓存中无效的对象,使我们避免提供陈旧的内容。 清漆缓存,有无数的方法可以做到这一点。 我们将探讨最常见的方式,以及如何部署它们。
清漆做了一大堆其他的东西为好,但其缓存服务是最流行 的。 缓存由在职缓存的静态内容加速Web服务 。 当光油缓存是提供一个高速缓存命中,它通常只是转储的内存块插入插座。 清漆缓存是如此之快,以至于,在现代硬件上,我们实际上测量微秒响应时间!
当使用高速缓存,你需要知道什么时候从缓存中逐出内容。 如果你没有办法驱逐的内容,那么你会在预定的时间量后,依靠缓存超时的对象。 这是一种方法,但几乎没有最优化的解决方案。 最好的办法是让光油缓存保持对象在内存中永远的(大部分),然后告诉该对象时刷新。 让我们详细讨论如何实现这一点。
HTTP吹扫
HTTP吹扫是最直接的这些方法。 而不是发送的GET /url
到光油,你会送PURGE /url
。 清漆然后将丢弃该对象从缓存中。 访问控制列表添加到光油,这样不只是任何人都可以从缓存中清除的对象; 除此之外,虽然,你到家了自由。
acl purge { "localhost"; "192.168.55.0"/24; } sub vcl_recv { # allow PURGE from localhost and 192.168.55... if (req.request == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } return (lookup); } } sub vcl_hit { if (req.request == "PURGE") { purge; error 200 "Purged."; } } sub vcl_miss { if (req.request == "PURGE") { purge; error 200 "Purged."; } }
吹扫的缺点
HTTP清洗达不到时,一块内容有复杂的关系,它出现在的URL。 新闻文章,例如,可能出现在多个网址。 这篇文章可能有一个桌面视图和移动视图,它可能出现在部分页面,并在头版。 因此,你必须要么得到的内容管理系统来跟踪所有这些表现还是让光油为你做它。 让光油做到这一点,你会使用的禁令,我们将进入现在。
禁令
禁令是针对光油,一个是经常被误解的功能。 它使您能够从服务在内存中的某些内容禁止光油,迫使光油获取这些页面的新版本。
一个有趣的方面是如何规定禁止的页面 。 清漆设有提供相当多的灵活性语言。 你能告诉光油禁止通过在命令行界面给人的禁令命令,通常连接到它与varnishadm
。 您也可以通过光油配置语言(VCL),它提供了实现基于HTTP的禁止一种简单的方式做到这一点。
让我们从一个例子。 假设我们需要清除本网站的所有图像。
> ban obj.http.content-type ~ “^image/”
这样做的结果是,在内存中的所有对象,HTTP响应头Content-Type
将匹配正则表达式^image/
,它会立即失效。
下面是在上光油会发生什么。 首先,禁令命令会将有关禁令“封杀名单”。当这个命令是禁止列表中,每个高速缓存命中,供应对象年纪比禁令本身会开始看禁令名单和对象比较的禁止名单上。 如果对象匹配,那么光油杀死它并获取较新的。 如果对象不匹配,那么光油会使它记下来,这样就不会再次进行检查。
让我们建立在我们的例子。 现在,我们只禁止那些在某处放置图像/feature
的URL。 注意,逻辑“与”运算, &&
。
> ban obj.http.content-type ~ “^image/” && req.url ~ “^/feature”
你会发现,它说obj.http.content-type
和req.url
。 在禁令的第一部分中,我们将存储在光油一个对象的属性。 在后者中,我们指的对一个对象的请求的一部分。 这可能是一个有点不合常规,但实际上你可以使用属性上的要求,在缓存中无效的对象。 现在, req.url
通常不存储在对象,所以指的是要求是我们可以在这里做的唯一的事情,你可以用这个做疯狂的事情 ,就像被要求由一个特定的客户端的IP地址禁止的一切,或禁止一切所要求的Chromium浏览器。 由于这些要求打光油,对象是无效的,并从源服务器刷新。
依赖于请求发出禁令开辟了一些有趣的可能性。 不过,有一个缺点的过程:禁令的一个很长的名单可能放缓的内容交付。
有分配给缩短禁令的名单,“禁令潜行者”的任务,一个工作线程。 这项禁令潜行者试图匹配适用对象的禁令。 当禁令已匹配年纪比自己所有的对象,它被丢弃。
通过禁令禁止潜行者迭代,它没有,它试图成为一个HTTP请求。 因此,依赖于从请求数据的任何禁止不能被禁止潜伏者进行测试。 为了保持禁令性能高达的话,我们会建议不使用的禁令请求数据。 如果你需要禁止的东西,通常是在请求中,如URL,您可以从请求中的数据复制到对象vcl_fetch
,像这样:
set beresp.http.x-url = req.url;
现在,你就可以使用上禁止obj.http.x-url
。 请记住, beresp
对象变成obj
,因为它被存储在高速缓存中。
标签内容为禁令
当你给光油有点帮助禁令往往很多更为有效。 如果对象具有X-Article-id
头,那么你并不需要知道所有的对象是作为的URL。
对于依赖几个对象的页面,你可以有内容管理系统增加一个X-depends-on
标题。 在这里,你会列出应触发当前文档的更新对象。 再次参加我们的新闻网站,你可以使用此列出头版提到的所有的文章:
X-depends-on: 3483 4376 32095 28372
当然,那么,如果文章之一发生变化,你会发出禁令,像这样:
ban obj.http.x-depends-on ~ “\D4376\D”
这是潜在的非常强大。 试想一下,通过触发器使数据库的问题这些无效宣告请求,从而消除了需要改变的中间件层。 整齐的,是吗?
优美的缓存失效
试想一下,清除的东西从上光油,然后这是应该更换突然死机的内容源服务器。 您刚刚扔掉的内容你唯一可行的副本。 你做了什么?! 原来,定期不少内容管理系统崩溃。
理想情况下,我们希望把对象在第三状态 – 无效它我们能够得到一些新的内容的条件。 这第三种状态存在于清漆:它被称为“宽限期”,它是使用基于TTL的废票。 一个对象过期后,它被保存在内存中的情况下后端服务器崩溃。 如果光油不能谈论到后端,然后它会检查是否有任何宽限对象匹配,并且它提供的不是。
一光油模块(或VMOD),命名为softpurge
,让你的对象是放入的恩典状态无效。 使用它很简单。 只需更换PURGE
与使用VCL的VCL softpurge
VMOD。
import softpurge; sub vcl_hit { if (req.method == "PURGE") { softpurge.softpurge(); error 200 “Successful softpurge”; } } sub vcl_miss { if (req.method == "PURGE) { softpurge.softpurge(); error 200 "Successful softpurge"; } }
分发缓存失效事件
所有上面列出的方法描述了一个缓存服务器上的内容无效化的处理。 最严重的结构将有一个以上的上光油服务器。 如果你有两个,应该给予足够的魅力对于大多数的网站,那么你将要发出一份失效事件为每个服务器。 但是,如果你有20或30光油的服务器,那么你真的不希望通过一个巨大的服务器列表有它循环陷入瘫痪的应用。
相反,你会希望有一个单一的API终点,你可以把你的大清洗 ,有它的失效事件分发到所有的服务器上光油。 作为参考,这里是一个用shell脚本非常简单无效的服务。 它将侦听端口2000和无效的URL到三个不同的服务器( alfa
, beta
和gamma
使用cURL)。
nc -l 2000 | while true do read url for srv in “alfa” “beta” “gamma” do curl -m 2 -x $srv -X PURGE $url done done
它可能不适合生产,因为错误处理留下的东西不理想!
缓存失效几乎是缓存同样重要。 因此,具有健全的策略无效的内容是至关重要的维持高水平的性能,并具有较高的高速缓存命中率。 如果你保持较高的命中率,那么你就需要更少的服务器上,将有更快乐的用户和可能减少停机时间。 有了这个,你是希望更舒适的使用这样的工具,以获得陈旧的内容了您的高速缓存。
近期评论