【问题标题】:Varnish and ESI, how is the performance?Varnish和ESI,性能如何?
【发布时间】:2011-08-23 01:37:38
【问题描述】:

我想知道现在 ESI 模块的性能如何?我在网上读过一些帖子,说清漆上的 ESI 性能实际上比真实的要慢。

假设我有一个包含超过 3500 个 esi 的页面,这将如何执行? esi 是为这种用途设计的吗?

【问题讨论】:

  • 我可以想办法找出来!制作一个包含 3500 个包含的页面并对其进行基准测试,我会对结果非常感兴趣 :)
  • 我很乐意这样做,但我对 varnish 很陌生,我认为这样的基准应该由专业人士执行。
  • 为什么要在一页中包含 3500 个内容?只是想想象这样的用例
  • 我在考虑 json 文档。特别是大文件。可以将不同的“子文档”与 esi:includes 链接在一起。假设您有一份文档,其中提供了员工列表,但它仅提供了员工的 ID,仅此而已。然后使用 ESI,您可以使其包含基于 ID 的员工信息。
  • 我可能会将获取作为单个请求包含在必要的员工列表中,而不是对其进行迭代。

标签: caching reverse-proxy varnish server-side-includes edge-side-includes


【解决方案1】:

我们使用 Varnish 和 ESI 将子文档嵌入到 JSON 文档中。基本上,我们的应用服务器的响应如下所示:

[
  <esi:include src="/station/best_of_80s" />,
  <esi:include src="/station/herrmerktradio" />,
  <esi:include src="/station/bluesclub" />,
  <esi:include src="/station/jazzloft" />,
  <esi:include src="/station/jahfari" />,
  <esi:include src="/station/maximix" />,
  <esi:include src="/station/ondalatina" />,
  <esi:include src="/station/deepgroove" />,
  <esi:include src="/station/germanyfm" />,
  <esi:include src="/station/alternativeworld" />
]

包含的资源本身就是完整且有效的 JSON 响应。所有站点的完整列表大约为 1070。因此,当缓存冷且完整的站点列表是第一个请求时,varnish 在我们的后端发出 1000 个请求。缓存热时ab是这样的:

$ ab -c 100 -n 1000 http://127.0.0.1/stations
[...]

Document Path:          /stations
Document Length:        2207910 bytes

Concurrency Level:      100
Time taken for tests:   10.075 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      2208412000 bytes
HTML transferred:       2207910000 bytes
Requests per second:    99.26 [#/sec] (mean)
Time per request:       1007.470 [ms] (mean)
Time per request:       10.075 [ms] (mean, across all concurrent requests)
Transfer rate:          214066.18 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   11   7.3      9      37
Processing:   466  971  97.4    951    1226
Waiting:        0   20  16.6     12      86
Total:        471  982  98.0    960    1230

Percentage of the requests served within a certain time (ms)
  50%    960
  66%    985
  75%    986
  80%    988
  90%   1141
  95%   1163
  98%   1221
  99%   1229
 100%   1230 (longest request)
$ 

100 rec/sec 看起来不太好,但请考虑文档的大小。 214066Kbytes/sec 使 1Gbit 接口过饱和。

带有热缓存 ab (ab -c 1 -n 1 ...) 的单个请求显示 83ms/req。

后端本身是基于 redis 的。我们在 NewRelic 中测量了 0.9 毫秒 [原文如此] 的平均响应时间。重新启动 Varnish 后,第一个使用冷缓存的请求(ab -c 1 -n 1 ...)显示 3158ms/rec。这意味着在生成响应时,每个 ESI 包含 Varnish 和我们的后端大约 3 毫秒。这是一个标准的核心 i7 比萨盒,有 8 个核心。我是在满载时测量的。我们以这种方式每月服务约 150mio req,命中率为 0.9。这些数字确实表明 ESI 包含是串行解析的。

在设计这样的系统时,您必须考虑 1) 当缓存冷时,您的后端能够在 Varnish 重新启动后承担负载,以及 2) 通常您的资源不会一次全部过期。对于我们的站点,它们每整小时过期一次,但我们会在过期标头中添加最多 120 秒的随机值。

希望对您有所帮助。

【讨论】:

  • 我刚刚想起我们在 Varnish 3.0.0 版本和 250 多个 ESI 中遇到了问题。请务必使用 3.0.2 或更高版本。
  • 到期时间非常好,您的解决方案非常聪明。绝对是偷那个!
【解决方案2】:

这不是第一手的,但我相信 Varnish 当前的 ESI 实现序列化包括请求;即,它们不是并发的。

如果是这样的话,在你提到的情况下,它确实会降低性能。

我会尝试让有第一手经验的人发表评论。

【讨论】:

  • 确实如此,这是 ESI 的 varnish 实现中的一个已知缺陷
  • 我可以在实际测试中确认:使用 php Symfony 2.6 安装:一个简单的主控制器/视图,它呈现(使用 render_esi)两个“子”控制器,每个控制器都有一个“睡眠( n)" 暂停,将按这种方式顺序渲染页面:首先,它渲染父视图。然后,它呈现第一个 esi:include 标记。然后渲染第二个。在我的示例中,只有父页面的 shared-max-age 为 600,并且正如预期的那样,这两个子页面永远不会被缓存。我希望它们是同时获取的,但实际上它们是按顺序获取的。
  • cernio - 什么版本的清漆?
【解决方案3】:

在 varnish 的**商业**版本中提供并行 ESI 请求:https://www.varnish-software.com/plus/parallel-esi/。片段请求的并行性质显然使由多个片段组成的页面的组装速度更快。

(这将是一个评论,但我没有足够的声誉这样做)

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 1970-01-01
    • 2011-10-27
    • 2012-01-18
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    相关资源
    最近更新 更多