【问题标题】:The behavior of varnish on MISS清漆在 MISS 上的行为
【发布时间】:2018-02-26 16:49:14
【问题描述】:

考虑这种情况: Varnish 缓存有一个 MISS 并且后端服务器现在正在重新生成请求的内容。在生成期间,第二个请求进入并获得 MISS。 varnish 是否在其他请求未决时将此请求发送到后端?如果在这段时间之间有数千个请求怎么办。服务器会崩溃吧?每个请求都会使其变慢。

这是正确的还是清漆“同步”这些场景以防止出现此类问题?

提前谢谢你!

【问题讨论】:

    标签: varnish


    【解决方案1】:

    Varnish 将所有请求发送到后端。 IE。它不会对其他请求进行排队,只发出一个后端请求并将其响应用于所有请求。

    不过,Varnish 有一个 grace option,可让您将旧的、过期的内容保存在缓存中,以应对这些类型的情况。

    例如考虑以下 VCL:

    sub vcl_recv {
      if (req.backend.healthy) {
        set req.grace = 5m;
      } else {
        set req.grace = 24h;
      }
    }
    
    sub vcl_fetch {
       set beresp.grace = 24h;
    }
    

    现在,如果后端运行状况良好(请参阅 backend polling)并且请求导致 MISS,则第一个请求将发送到后端。如果另一个请求针对相同的内容,但缓存中有一个年龄 MISS 的第一个请求从后端获得响应(并且缓存再次刷新)或项目的年龄大于 TTL+req.grace,就会发生这种情况。

    如果后端关闭 (req.backend.healthy == FALSE),过时的内容将被提供只要 age

    您可能还想查看Varnish bookSaving a request 部分以获得更详尽的示例和练习。

    固定:未转义的

    修复更多:还有一个未转义的

    【讨论】:

    • 我注意到我的答案中有一个未转义的
    • 嗯,我仍然有一个问题,如果在停电或崩溃后缓存为空,会发生什么。我们的网站被大量访问,导致每秒有许多请求。我认为如果 varnish 有一个空缓存,它可能会杀死我们的网络服务器。这就是为什么我希望清漆会让相等的请求等待并且只执行一次的原因。之后其他人将从缓存中获得答案。所以服务器只会做一次像主页这样的请求。而不是并行1000次。关于这个问题有什么想法吗?
    • 我读到现在它会在宽限期内交付旧内容。同时 varnish 尝试使用对后端的请求来更新缓存。当缓存更新时,varnish 将为新请求提供请求的实际内容。因此在更新缓存之前它不会将它们排队。在对象的生命周期加上宽限期过去之后,varnish 不会从缓存中传递任何东西,它会尝试询问后端。您的后端应该确实能够在宽限期内交付请求的内容。
    • 对于 url 更新清漆不会将多个请求并行发送到后端。这会在网络服务器上产生愚蠢的负载并减慢速度。如果我是假的,请纠正我!
    • 如果您想扩展您的问题,请考虑编辑原始问题或发布新问题。如果我正确理解了您的评论,那么您是在问宽限期内会发生什么。缓存对象过期后(对象年龄大于 TTL),Client#1 将其请求发送到后端,而 Client#2-n 获取缓存版本。在上面的例子中,客户#1 应该在 5 分钟内得到他/她的回复。如果需要更长的时间,您应该考虑其他加快页面速度的方法。
    【解决方案2】:

    我认为 Ketola 的(已接受)答案是错误的。

    对同一个 URI 的多个 Varnish 请求排队。

    然后取决于第一个请求的结果是否可缓存。如果是,它也将用于其他(排队的)请求。 如果没有,所有其他排队的请求将被发送到后端。

    因此,如果您想要缓存一些缓慢的 API 端点,并且它是可缓存的(关于 Varnish 规则),那么多个请求将只针对该 URI 到达后端一次。

    【讨论】:

      【解决方案3】:

      我对@max_i 的回答没有意见或任何意见,所以我提交另一个回答来验证他的回答。

      Ketola 接受的答案并非完全错误,它可能只是过时了,并且对于旧版本的 Varnish 可能是正确的。具体这部分:

      Varnish 将所有请求发送到后端。 IE。它不会对其他请求进行排队,只发出一个后端请求并将其响应用于所有请求。

      在使用 Varnish 4.1 LTS 和 Apache 2.4 的标准安装独立测试后,我创建了一个基本的 PHP 文件,其中包含以下内容:

      <?php sleep(5); echo 'hello world!';
      

      然后使用ab 测试了使用50个请求在5个并发下的HTTP请求周期。结果表明,虽然 Varnish 接受了每一个连接,但只向后端发出了一个请求,正如预期的那样,该请求大约需要 5 秒才能解决。随后,每个 Varnish 连接都必须等待该最短时间才能收到响应。

      这样做的缺点当然是第一个请求之后的请求在其后面“排队”,但与同时到达后端的所有 50 个请求相比,这当然是一个小问题(或者在我的测试中,并发数为 5)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-16
        • 2014-03-14
        • 2012-09-20
        • 2017-06-10
        • 2018-03-01
        • 2017-12-18
        • 1970-01-01
        • 2018-11-16
        相关资源
        最近更新 更多