清漆默认宽限期行为
Varnish default grace behavior
有一些 api 负载很重的资源,其中响应是动态的,为了卸载我们使用 Varnish 作为前端缓存层的原始服务器。 api 以 cache-control headers 响应,范围从 max-age=5 到 max-age=15。由于我们使用的是低缓存 ttl,因此很多请求仍然以后端获取结束。从这个意义上说,我们不确定我们是否理解清漆请求在优雅方面是否正确合并。我们没有触及任何宽限度设置,使用来自 VCL 的宽限期 og 从后端发送 stale-while-revalidate headers。
所以问题是;资源从缓存中过期后,所有对该资源的请求都将在 varnish 中等待,直到资源再次在缓存中刷新,以防止雷群问题?或者默认的宽限期设置是否会阻止“等待”请求,因为在后端获取完成时将向它们提供“陈旧”内容?从文档中我们不清楚默认值是如何工作的。
关于 Varnishobject 生命周期的基础知识
object 的总生命周期是以下各项的总和:
TTL + grace + keep
让我们分解一下:
- TTL 定义内容的新鲜度
- Grace 用于异步重新验证过期内容
- Keep 用于过期内容的同步重新生效
执行顺序如下:
- 只要 TTL 未过期,就会从缓存中提供 object
- 当 TTL 等于或小于零时,需要重新验证
- 只要剩余 TTL(可能小于零)和宽限时间之和大于零,就可以提供陈旧的内容
- 如果有足够的宽限时间,Varnish 将在提供陈旧内容的同时异步重新验证内容
- 如果 TTL 和宽限期都已过期,则需要同步重新生效
- 同步重新验证使用等待列表并受请求合并影响
- 剩余的保持时间将确保 object 保持不变,以便可以发生条件请求
默认值
- 根据 http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-ttl 默认 TTL 设置为 120 秒
- 根据http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-grace默认的grace设置为10秒
- 根据http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-keep默认keep设置为0秒
请求合并怎么样?
Varnish中用于请求合并的等待列表仅用于non-cached objects或过期的objects已经过了宽限期。
以下情况不会触发请求合并:
TTL > 0
TTL + grace > 0
当 object 新鲜或在宽限期内时,无需使用等待列表,因为内容仍将从缓存中提供。在 objects 宽限期的情况下,单个异步后端请求将被发送到源以进行重新验证。
当 object 不在缓存中或超出宽限期时,需要同步重新验证,这是一个阻塞操作。为避免在多个客户端请求相同 object 时出现问题,使用等待列表并将这些请求合并为一个后端请求。
最后,所有排队的请求都由同一个后端响应并行满足。
绕过等候名单
但这里有一条关于请求合并的重要评论:
Request coalescing only works for cacheable content. Stateful content that can never be satisfied by a coalesced response should bypass the waiting list. If not, serialization will take place.
序列化是一件坏事。这意味着排队的请求不能被响应满足,并且被串行处理。此 head-of-line 阻塞会导致严重延迟。
这就是 stateless/uncacheable 内容应该绕过等候名单的原因。
绕过等待列表的决定是由 hit-for-miss 缓存 做出的。这种机制缓存决定不缓存。
以下代码用于此:
set beresp.ttl = 120s;
set beresp.uncacheable = true;
这是您可以在 Varnish 的 built-in VCL 中找到的那种 VCL 代码。当找到 Set-Cookie
header 或出现 Cache-Control: private, no-cache, no-store
时触发。
这意味着在接下来的 2 分钟内,object 将从源站提供服务,等待名单将被绕过。当下一个缓存未命中将 return 可缓存响应时,object 仍存储在缓存中,并且 hit-for-miss 不再适用。
考虑到这一点,不要将 beresp.ttl
设置为零是至关重要的。因为那会使 hit-for-miss 信息过期,并且仍然会导致下一个请求在等待列表中结束,即使我们知道响应将不可缓存。
有一些 api 负载很重的资源,其中响应是动态的,为了卸载我们使用 Varnish 作为前端缓存层的原始服务器。 api 以 cache-control headers 响应,范围从 max-age=5 到 max-age=15。由于我们使用的是低缓存 ttl,因此很多请求仍然以后端获取结束。从这个意义上说,我们不确定我们是否理解清漆请求在优雅方面是否正确合并。我们没有触及任何宽限度设置,使用来自 VCL 的宽限期 og 从后端发送 stale-while-revalidate headers。
所以问题是;资源从缓存中过期后,所有对该资源的请求都将在 varnish 中等待,直到资源再次在缓存中刷新,以防止雷群问题?或者默认的宽限期设置是否会阻止“等待”请求,因为在后端获取完成时将向它们提供“陈旧”内容?从文档中我们不清楚默认值是如何工作的。
关于 Varnishobject 生命周期的基础知识
object 的总生命周期是以下各项的总和:
TTL + grace + keep
让我们分解一下:
- TTL 定义内容的新鲜度
- Grace 用于异步重新验证过期内容
- Keep 用于过期内容的同步重新生效
执行顺序如下:
- 只要 TTL 未过期,就会从缓存中提供 object
- 当 TTL 等于或小于零时,需要重新验证
- 只要剩余 TTL(可能小于零)和宽限时间之和大于零,就可以提供陈旧的内容
- 如果有足够的宽限时间,Varnish 将在提供陈旧内容的同时异步重新验证内容
- 如果 TTL 和宽限期都已过期,则需要同步重新生效
- 同步重新验证使用等待列表并受请求合并影响
- 剩余的保持时间将确保 object 保持不变,以便可以发生条件请求
默认值
- 根据 http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-ttl 默认 TTL 设置为 120 秒
- 根据http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-grace默认的grace设置为10秒
- 根据http://varnish-cache.org/docs/trunk/reference/varnishd.html#default-keep默认keep设置为0秒
请求合并怎么样?
Varnish中用于请求合并的等待列表仅用于non-cached objects或过期的objects已经过了宽限期。
以下情况不会触发请求合并:
TTL > 0
TTL + grace > 0
当 object 新鲜或在宽限期内时,无需使用等待列表,因为内容仍将从缓存中提供。在 objects 宽限期的情况下,单个异步后端请求将被发送到源以进行重新验证。
当 object 不在缓存中或超出宽限期时,需要同步重新验证,这是一个阻塞操作。为避免在多个客户端请求相同 object 时出现问题,使用等待列表并将这些请求合并为一个后端请求。
最后,所有排队的请求都由同一个后端响应并行满足。
绕过等候名单
但这里有一条关于请求合并的重要评论:
Request coalescing only works for cacheable content. Stateful content that can never be satisfied by a coalesced response should bypass the waiting list. If not, serialization will take place.
序列化是一件坏事。这意味着排队的请求不能被响应满足,并且被串行处理。此 head-of-line 阻塞会导致严重延迟。
这就是 stateless/uncacheable 内容应该绕过等候名单的原因。
绕过等待列表的决定是由 hit-for-miss 缓存 做出的。这种机制缓存决定不缓存。
以下代码用于此:
set beresp.ttl = 120s;
set beresp.uncacheable = true;
这是您可以在 Varnish 的 built-in VCL 中找到的那种 VCL 代码。当找到 Set-Cookie
header 或出现 Cache-Control: private, no-cache, no-store
时触发。
这意味着在接下来的 2 分钟内,object 将从源站提供服务,等待名单将被绕过。当下一个缓存未命中将 return 可缓存响应时,object 仍存储在缓存中,并且 hit-for-miss 不再适用。
考虑到这一点,不要将 beresp.ttl
设置为零是至关重要的。因为那会使 hit-for-miss 信息过期,并且仍然会导致下一个请求在等待列表中结束,即使我们知道响应将不可缓存。