NGINX的缓存介绍(一)

我们都知道应用程序和网站的性能是他们成功的关键因素。但是,使应用程序或网站性能更好的过程并不总是很清楚。代码质量和基础架构当然是至关重要的,但在许多情况下,您可以通过专注于一些非常基本的应用程序交付技术,对应用程序的最终用户体验进行大量改进。其中一个例子是在应用程序堆栈中实现和优化缓存。此博客文章介绍的技术可以帮助新手和高级用户使用NGINX中包含的内容缓存功能,从而获得更好的性能。

概观

内容缓存位于客户端和“源服务器”之间,并保存它看到的所有内容的副本。如果客户端请求缓存已存储的内容,则它会直接返回内容而不联系源服务器。这提高了性能,因为内容缓存更接近客户端,并且更有效地使用应用程序服务器,因为它们不必每次都从头开始生成页面。

Web浏览器和应用程序服务器之间可能存在多个缓存:客户端的浏览器缓存,中间缓存,内容交付网络(CDN)以及位于应用程序服务器前面的负载平衡器或反向代理。即使在反向代理/负载均衡器级别,缓存也可以极大地提高性能。

作为一个例子,去年我承担了性能调整任务缓慢加载的网站的任务。我注意到的第一件事就是生成主页需要1秒多的时间。经过一些调试后,我发现因为页面被标记为不可缓存,所以它是动态生成的,以响应每个请求。页面本身并没有经常更改,也没有个性化,因此没有必要。作为一项实验,我将主页标记为由负载均衡器缓存5秒钟,这样做会带来明显的改善。第一个字节的时间下降到几毫秒,页面加载速度明显加快。

NGINX通常部署为应用程序堆栈中的反向代理或负载平衡器,并具有一整套缓存功能。下一节将讨论如何使用NGINX配置基本缓存。

如何设置和配置基本缓存

启用基本缓存只需要两个指令:proxy_cache_path和proxy_cache。 proxy_cache_path指令设置缓存的路径和配置,proxy_cache指令激活它。

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

server {
    # ...
    location / {
        proxy_cache my_cache;
        proxy_pass http://my_upstream;
    }
}

proxy_cache_path指令的参数定义以下设置:

  • 缓存的本地磁盘目录称为/ path / to / cache /。
  • levels在/ path / to / cache /下设置一个两级目录层次结构。在单个目录中包含大量文件会降低文件访问速度,因此我们建议对大多数部署使用两级目录层次结构。如果未包含levels参数,则NGINX会将所有文件放在同一目录中。
  • keys_zone设置共享内存区域,用于存储缓存键和元数据,例如使用计时器。拥有内存中的密钥副本,NGINX可以快速确定请求是HIT还是MISS而无需转到磁盘,从而大大加快了检查速度。 1 MB区域可以存储大约8,000个密钥的数据,因此示例中配置的10 MB区域可以存储大约80,000个密钥的数据。
  • max_size设置缓存大小的上限(在本例中为10千兆字节)。它是可选的;不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限制时,称为缓存管理器的进程将删除最近最少用于将缓存大小恢复到限制之下的文件。
  • inactive指定项目在未被访问的情况下可以保留在缓存中的时间长度。在此示例中,缓存管理器进程会自动从缓存中删除60分钟未请求的文件,无论其是否已过期。默认值为10分钟(10米)。非活动内容与过期内容不同。 NGINX不会自动删除缓存控件头定义的已过期内容(例如,Cache-Control:max-age = 120)。过期(陈旧)内容仅在非活动指定的时间内未被访问时被删除。访问过期内容时,NGINX会从原始服务器刷新它并重置非活动计时器。
  • NGINX首先将发往高速缓​​存的文件写入临时存储区域,use_temp_path = off指令指示NGINX将它们写入将被高速缓存的相同目录。我们建议您将此参数设置为off,以避免在文件系统之间进行不必要的数据复制。 use_temp_path是在NGINX 1.7.10和NGINX Plus R6中引入的。

最后,proxy_cache指令激活与父位置块的URL匹配的所有内容的缓存(在示例中为/)。您还可以在服务器块中包含proxy_cache指令;它适用于没有自己的proxy_cache指令的服务器的所有位置块。

原点关闭时提供缓存内容

NGINX内容缓存的一个强大功能是,NGINX可以配置为在无法从原始服务器获取新内容时从其缓存中提供陈旧内容。如果缓存资源的所有原始服务器都已关闭或暂时繁忙,则会发生这种情况。 NGINX不是将错误传递给客户端,而是从缓存中提供文件的陈旧版本。这为NGINX代理的服务器提供了额外的容错能力,并确保在服务器故障或流量高峰时的正常运行时间。要启用此功能,请包含proxy_cache_use_stale指令:

location / {
    # ...
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
}

使用此示例配置,如果NGINX收到来自原始服务器的错误,超时或任何指定的5xx错误,并且在其缓存中有所请求文件的过时版本,则会传递过时文件,而不是将错误转发给客户。

微调缓存并提高性能

NGINX具有丰富的可选设置,可用于微调缓存的性能。这是一个激活其中一些的例子:

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

server {
    # ...
    location / {
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502
                              http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;

        proxy_pass http://my_upstream;
    }
}

这些指令配置以下行为:

  • proxy_cache_revalidate指示NGINX在从源服务器刷新内容时使用条件GET请求。如果客户端请求缓存但是由缓存控制头定义的过期的项目,则NGINX在其发送到源服务器的GET请求的头部中包括If-Modified-Since字段。这节省了带宽,因为服务器仅在NGINX最初缓存它时,自从记录在附加到文件的Last-Modified标头中记录的时间后,才发送完整项目。
  • proxy_cache_min_uses设置客户端在NGINX缓存之前必须请求项目的次数。如果缓存不断填满,这很有用,因为它确保只将最常访问的项添加到缓存中。默认情况下,proxy_cache_min_uses设置为1。
  • proxy_cache_use_stale指令的更新参数与启用proxy_cache_background_update指令相结合,指示NGINX在客户端请求已过期或正在从源服务器更新的项目时提供过时内容。所有更新都将在后台完成。在完全下载更新的文件之前,将为所有请求返回陈旧文件。
  • 启用proxy_cache_lock后,如果多个客户端请求缓存中的当前文件(MISS),则只允许第一个请求通过源服务器。其余请求等待满足该请求,然后从缓存中提取文件。如果未启用proxy_cache_lock,则导致缓存未命中的所有请求将直接发送到源服务器。

跨多个硬盘拆分缓存

使用NGINX,无需构建RAID。如果有多个硬盘驱动器,可以使用NGINX在它们之间拆分缓存。以下示例根据请求URI将客户端均匀分布在两个硬盘驱动器上:

proxy_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m
                 max_size=10g inactive=60m use_temp_path=off;
proxy_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m
                 max_size=10g inactive=60m use_temp_path=off;

split_clients $request_uri $my_cache {
              50%          “my_cache_hdd1”;
              50%          “my_cache_hdd2”;
}

server {
    # ...
    location / {
        proxy_cache $my_cache;
        proxy_pass http://my_upstream;
    }
}

两个proxy_cache_path指令在两个不同的硬盘驱动器上定义了两个缓存(my_cache_hdd1和my_cache_hdd2)。 split_clients配置块指定一半请求(50%)的结果缓存在my_cache_hdd1中,另一半缓存在my_cache_hdd2中。基于$ request_uri变量(请求URI)的散列确定每个请求使用哪个缓存,结果是对给定URI的请求始终缓存在同一缓存中。

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/83904303