[译]NGINX高性能缓存实践(下)

原文:High-Performance Caching with NGINX and NGINX Plus

译者:杰微刊兼职翻译巫明瀚  


[译]NGINX高性能缓存实践(上)

http://www.jointforce.com/jfperiodical/article/3089

[译]NGINX高性能缓存实践(中)

http://www.jointforce.com/jfperiodical/article/3096


这篇文章是从一次webinar(互联网大会)修改了来的,由Owen Garrett创作,Andrew Alexeev介绍。


提纲

0:00 介绍

1:22 关于Webinar

2:17 内容缓存基础概念

2:35 基本原则

3:59 HTTP缓存机制

7:46 NGINX到底缓存些什么?

用NGINX进行内容缓存

9:55 NGINX操作

10:06 NGINX配置

11:14 缓存过程

15:32 非HTTP缓存

17:10 如何理解底层机制

17:38 缓存监控

19:08 缓存监控(Cont.)

20:09 扩展状态

21:57 内容缓存在NGINX中的运行方式

22:40 缓存具体如何工作

23:53 缓存是如何存储的?

26:36 从磁盘中载入缓存

28:07 管理磁盘缓存

29:22 从磁盘上删除内容

控制缓存

31:27 控制缓存

32:30 延迟缓存

34:45 控制缓存时间

36:18 缓存还是不缓存

37:25 多重缓存

39:07 快速回顾 - 为什么要缓存?

39:44 为什么网页速度重要

40:46 Google改变了规则

41:28 糟糕性能的代价

43:00 NGINX缓存带你飞

45:21 结语

Q&A

47:15 Q&A


34:45 控制缓存时间


你对缓存具体要缓存多久有着非常好的控制力。上游服务器经常会包含一些对浏览器友好的头——比如对经常访问的内容设置比较长的缓存时间。然而你一般会希望NGINX能够更频繁的更新内容。


如果我们直接把浏览器的缓存从60秒减到10秒,服务器的负载会增大非常多,但是把NGINX的缓存超时从60秒设到10秒几乎没什么开销。对每一种请求,每分钟只会增加5个左右的请求到上游服务器,如果让浏览器之类的远程客户端来决定缓存时间,那么负载的增加取决于到底有多少活跃的远程客户端。


因此我们可以覆盖这个逻辑,无视掉上游服务器的意图。我们可以通过让NGINX无视掉特定的头:X-Accel-Expires,Cache-Control或者Expires。然后你就可以在配置文件里用proxy_cache_valid指令来提供你希望的默认缓存时间。


36:18缓存还是不缓存


有时候你可能不希望缓存特定的内容,仅管上游服务器说可以缓存,或者你希望我们绕过NGINX里面存储的缓存。proxy_cache_bypass和proxy_no_cache指令来完成这些控制。


你可以用他们作为快捷方式来表达,如果请求包含某些头,比如HTTP验证头,或者包含某些HTTP参数,那么就绕过缓存——要么自动更新缓存,要么完全跳过缓存直接把请求转发给上游服务器。


一般来说只有非常复杂的缓存场景才会使用这些技巧,当你需要仔细的根据cookie或者认证头的值来决定是否需要缓存某些内容,以及某些东西是否总需要从上游服务器获取,以及哪些东西永远不应该被NGINX缓存。


37:25 多重缓存


最后,对于那些大型分布式部署的应用,你可能希望在一个NGINX实例中使用使用多重缓存机制,原因有好几个。可能对于不同租户(使用NGINX作为前端的服务)你有不同的需求,比如他们有不同的特点,比如他们的重要程度不同,甚至在某些共享服务器的场景下他们有着不同预算。


可能你在NGINX服务器上有若干个磁盘,那么最有效率的方式就是在每个磁盘上部署不同的缓存。这里的黄金法则是尽量减少跨磁盘的文件复制,我们可以通过给每个磁盘都设置一个缓存,然后让每个代理都包含磁盘上对应的这个文件。


标准的操作流程是,当NGINX收到了来自上游代理的内容时,他会直接把内容存到磁盘上除非内容足够小,在内存里就能放下。接下来一旦内容被存到了磁盘上,他就会被移动到缓存中去。这个操作将会非常高效,如果临时文件跟缓存是在同一个磁盘。


39:07 快速回顾 - 为什么要缓存?


好了, 我们讨论了缓存,讨论了NGINX缓存的方法和实现,讨论了你怎么配置它们。我们离飞上天已经很近了,现在让我们快速的回顾一下你到底为什么需要缓存内容。NGINX在全世界超过1亿1400万网站上被部署着,很多用户部署NGINX的目的是为了使用它的网页加速和内容缓存功能。(这些统计是基于2014年5月的数据)


39:44 为什么网页速度重要


这些功能提高了网站的访问速度——他们让用户有了更好的体验——因此网页速度真的非常非常重要。多少年来,不断地有测试在检测用户表现和网站速度之间的关系,后来被人们称之为“N秒规则”。这里指的是一个用户平均会使用多久来等待一个网站载入并渲染完毕。否则他们就会前往别的网站,比如竞争对手的。


随着标准不断地在提高,用户的期待也越来越高,用户们愿意等待的时间也越来越短了。你可以通过一些简单模糊的数据计算就能推断出用户在2016年愿意接受的等待时间是负数。


40:46 Google改变了规则


实际上,技术改变了了我们。Google在几年前Google实时搜索刚出现时发布了这张图。现在你使用google的时候,只要写了一个关键词,甚至在你写完之前Google就会显示可选的搜索结果。这描述了用户对现代互联网期待上巨大的变化。就像Google自己说的,“用户们希望现在网页的表现就像自己翻书的表现一样”——流畅而且快速。


41:28 糟糕性能的代价


如果你没有达到用户对性能的期待,那么这一切对你的KPI的影响可能非常严重。对于广告点击率,Google说他们发现仅仅因为慢了半秒钟,点击率下降了20%。对于收入:在某些关于慢速网页的过激的研究中,亚马逊过激的增加了他们的网页加载延时几百毫秒,然后发现那些来自被影响的用户的收入每慢100ms就会降低1%。


还有很多类似的网页检测和调查都在不同的维度上反映出了类似的问题,比如用户停留时间,用户的反弹率。最近Google还把网页的载入速度纳入了搜索中PageRank的评价体系中去。其中考虑的是第一个字节的到达时间。第一个字节到的越慢,你的网站遭到的降权越严重。一个网站如果被google放在了第三页第四页,甚至第五页,他根本就不会被用户访问到。


43:00 NGINX缓存带你飞


NGINX的缓存功能可以大大的提高你的用户体验,降低第一个字节到达的时间,让网站感受起来更流畅。


NGINX让你的网站构架更简单,更紧凑。NGINX并不仅仅是单独的网页缓存,他还包含了一个网页的源服务器,包括了一个类似FastCGI的网关,在NGINX Plus中,他还包含了构建一套复杂,成熟的负载平衡工具和应用分发控制器。这可以让你把好几个不同的网络组建合并到一个组件中去——NGINX或者NGINX Plus——让你的方案更可靠,更可调式,更快。


NGINX可以提高服务器的负载能力,他把上游服务器的那些重复任务给分摊掉了。实际上,某些不可以被缓存的内容(比如博客的某些前端页面),也有被缓存一两秒钟的价值。


当有一百个用户在同一秒访问同一个资源的时候,NGINX就会把那些请求压缩到一个请求给源服务器,然后把这些内容返回给用户,并且保证不会有超过一秒的过期。对于一般的博客网站或者类似的网站,这远远足够了,而且能带来极大的性能提升——不仅在上游服务器的负载上还是你在部署和管理上的投资。


最后别忘了,NGINX的使用策略:用use stale功能来降低上游服务器故障时的损失。如果他们跑的很慢,如果他们报错了,如果他们出现了某些故障,NGINX都可以回滚到老的缓存版本,并且一直使用他们直到我们的上游服务器恢复。


45:21 结语


世界上38%最繁忙的网站都是用NGINX来完成他们大部分的网站加速和内容缓存功能。(编辑:这些统计基于2014年的数据,在这里看现在的数据)。需要更多的解决方案和细节的话可以看我们的博客和功能简介,在nginx.com。里面主要包含了NGINX和NGINX Plus的功能。也可以来看下我们的webinar列表,不仅仅有未来的webinras(网络交流会),也包括最近添加的系列。


如果你希望探索更多的功能,你可以参考nginx.org和nginx.com,但是最好还是下下来试试吧!开源的产品可以在nginx.org找到。商业版本,包含了负载均衡,应用分发,管理,以及易用性等功能,请访问nginx.com。


好了,基佬们,谢谢你们花时间听我的演说,希望这些演说的内容和关于内容缓存的简洁对你们有用。


Q&A

让我们进入问答环节吧。


47:20 Byte?Range 请求

我有一个关于byte-range请求的问题。Byte-range当用户请求一个内容,但是只需要那个内容的一部分的时候要用到,比如一个视频文件,客户端是需要看到视频文件的一部分。或者在PDF中比较常见,用户希望阅读PDF的索引,之后用户可能只想下载一些特定的页面。这些功能在NGINX的内容缓存中是如何工作的?


整个过程是这样的,当NGINX得到了byte-range请求之后,如果整个资源都在缓存里面,NGINX会从缓存里面返回需要的字节.如果资源不在缓里面,NGINX会向服务器请求完整的资源,并且把资源缓存下来.目前NGINX不会尊重byte-range请求,并且会返回完整的资源给客户端,在大多数情况下这都是可以接受的表现。


比如一个客户端要下载PDF文档,他的第一个请求总是完整的,只有当第一个请求被发送结果又中断了的时候才会开始发送byte-range请求。因此,对于缓存下来的内容,nginx尊重byte-range请求,对于没有缓存下来的内容,NGINX读取完整的内容并且流式传输给客户端。


49:13 代理缓存重验证

这个问题是关于NGINX的代理缓存重新验证机制的。这个机制允许NGINX发送一个条件GET请求给上游服务器来检测内容是否发生了改变,问题的内容是: 代理缓存到底是尊重ETag还是仅仅看If-Modified-Since的时间?


答案是,仅仅检测If-Modified-Since,而且作为最佳实践的一条,最好总是包含If-Modified-Since在返回内容中,然后把ETag当做一个可选项,因为他们的支持不是很好,或者至少没有“last modified”日期这么广泛。


50:07 均匀的把缓存分布到所有磁盘。

NGINX能够针对一个单独的网站吧所有的缓存均匀的分布到所有磁盘来达到最好的性能吗?


是的,可以,但是可能需要一些工作。部署一系列没有RAID的磁盘,然后分别部署缓存,是比较典型的场景。其中需要做一些分区和配置的工作。如果你需要配置这些东西,你可以联系我们的社区,我们会在哪里处理你的要求的,或者你也可以用我们的NGINX-Plus,然后联系我们的支持团队,我们非常乐意服务。


50:50 Vary头

NGINX会在缓存命中中考虑Vary头的影响吗?

不, NGINX不会自动处理Vary头。如果这是个问题,那么把Vary头加入到Nginx的代理cache key去就好了。这样就可以存储不同的版本了。


51:25 缓存元语

所有缓存元语和指令都被支持吗?

基本上是的,尽管有些边界条件比如Vary头,并不被支持。在很多情况下RFC所规定的缓存解释方式都有所区别。我们会尽可能支持那些稳定一致,而且容易配置的部分。


51:52 上游头和数据

上游的头和数据都会被缓存吗?

是的。如果你收到了一个来自缓存的返回值,那么头和内容都会被缓存。


52:13 *-Encoding Headers

我很惊讶NGINX居然不支持直接使用不同的Transfer-Coding的组合。

Accept-Encoding一般都是通过Vary头来实现的,之前的评论中提到过我们得把Vary头放到cache key中去,这同样适用于客户端不支持他们的情况。


Q: 其他的内容缓存跟NGINX比起来有什么区别?

CDN是非常有效地内容缓存方案。CDN是以服务的方式被部署的。你对他们的控制权非常有限,不论是对缓存的内容还是内部的超时机制都是如此。但是他们对于把内容放到离用户更近的地方真的非常非常有用。NGINX是加速网页应用的有效工具,而且一般来说两者都会部署。至于那些独立缓存比如varnish,他们是非常非常厉害的前端缓存技术,而且在很多地方跟NGINX很相似。NGINX的一个最大的优点就是他把很多上游服务,网关,缓存,和负载均衡集成到了一个解决方案里面。这样你就有了一个更简单紧凑的构架解决方案。而且更容易维护,更好调试,更容易诊断问题。

JF

微信关注《大话程序员》,

每天两篇新奇有趣的互联网读物。


扫描或长按识

相关文章
相关标签/搜索