NGINX 緩存使用指南


NGINX 緩存使用指南 [proxy_cache]

Nginx

  一個web緩存坐落於客戶端和“原始服務器(origin server)”中間,它保留了所有可見內容的拷貝。如果一個客戶端請求的內容在緩存中存儲,則可以直接在緩存中獲得該內容而不需要與服務器通信。這樣一來,由於web緩存距離客戶端“更近”,就可以提高響應性能,並更有效率的使用應用服務器,因為服務器不用每次請求都進行頁面生成工作。 
在瀏覽器和應用服務器之間,存在多種“潛在”緩存,如:客戶端瀏覽器緩存、中間緩存、內容分發網絡(CDN)和服務器上的負載平衡和反向代理。緩存,僅在反向代理和負載均衡的層面,就對性能提高有很大的幫助。

  Nginx從0.7.48版本開始,支持了類似Squid的緩存功能。這個緩存是把URL及相關組合當作Key,用md5編碼哈希后保存在硬盤上,所以它可以支持任意URL鏈接,同時也支持404/301/302這樣的非200狀態碼。雖然目前官方的Nginx Web緩存服務只能為指定URL或狀態碼設置過期時間,不支持類似Squid的PURGE指令,手動清除指定緩存頁面,但是,通過一個第三方的Nginx模塊,可以清除指定URL的緩存。

  Nginx的Web緩存服務主要由proxy_cache相關指令集和fastcgi_cache相關指令集構成,前者用於反向代理時,對后端內容源服務器進行緩存,后者主要用於對FastCGI的動態程序進行緩存。兩者的功能基本上一樣。

  最新的Nginx 0.8.32版本,proxy_cache和fastcgi_cache已經比較完善,加上第三方的ngx_cache_purge模塊(用於清除指定URL的緩存),已經可以完全取代Squid。我們已經在生產環境使用了 Nginx 的 proxy_cache 緩存功能超過兩個月,十分穩定,速度不遜於 Squid。

  在功能上,Nginx已經具備Squid所擁有的Web緩存加速功能、清除指定URL緩存的功能。而在性能上,Nginx對多核CPU的利用,勝過Squid不少。另外,在反向代理、負載均衡、健康檢查、后端服務器故障轉移、Rewrite重寫、易用性上,Nginx也比Squid強大得多。這使得一台Nginx可以同時作為“負載均衡服務器”與“Web緩存服務器”來使用。

 

一、如何安裝和配置基礎緩存

我們只需要兩個命令就可以啟用基礎緩存: proxy_cache_pathproxy_cache 
proxy_cache_path用來設置緩存的路徑和配置,proxy_cache用來啟用緩存。

 
  1. proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
  2. use_temp_path=off;
  3. server {
  4. ...
  5. location / {
  6. proxy_cache my_cache;
  7. proxy_pass http://my_upstream;
  8. }
  9. }

proxy_cache_path命令中的參數及對應配置說明如下:

1.用於緩存的本地磁盤目錄是/path/to/cache/

2.levels在/path/to/cache/設置了一個兩級層次結構的目錄。將大量的文件放置在單個目錄中會導致文件訪問緩慢,所以針對大多數部署,我們推薦使用兩級目錄層次結構。如果levels參數沒有配置,則NGINX會將所有的文件放到同一個目錄中。

3.keys_zone設置一個共享內存區,該內存區用於存儲緩存鍵和元數據,有些類似計時器的用途。將鍵的拷貝放入內存可以使NGINX在不檢索磁盤的情況下快速決定一個請求是HIT還是MISS,這樣大大提高了檢索速度。一個1MB的內存空間可以存儲大約8000個key,那么上面配置的10MB內存空間可以存儲差不多80000個key。

4.max_size設置了緩存的上限(在上面的例子中是10G)。這是一個可選項;如果不指定具體值,那就是允許緩存不斷增長,占用所有可用的磁盤空間。當緩存達到這個上線,處理器便調用cache 
manager來移除最近最少被使用的文件,這樣把緩存的空間降低至這個限制之下。

5.inactive指定了項目在不被訪問的情況下能夠在內存中保持的時間。在上面的例子中,如果一個文件在60分鍾之內沒有被請求,則緩存管理將會自動將其在內存中刪除,不管該文件是否過期。該參數默認值為10分鍾(10m)。注意,非活動內容有別於過期內容。NGINX不會自動刪除由緩存控制頭部指定的過期內容(本例中Cache-Control:max-age=120)。過期內容只有在inactive指定時間內沒有被訪問的情況下才會被刪除。如果過期內容被訪問了,那么NGINX就會將其從原服務器上刷新,並更新對應的inactive計時器。

6.NGINX最初會將注定寫入緩存的文件先放入一個臨時存儲區域, use_temp_path=off命令指示NGINX將在緩存這些文件時將它們寫入同一個目錄下。我們強烈建議你將參數設置為off來避免在文件系統中不必要的數據拷貝。use_temp_path在NGINX1.7版本和NGINX Plus R6中有所介紹。

最終, proxy_cache命令啟動緩存那些URL與location部分匹配的內容(本例中,為/)。你同樣可以將proxy_cache命令添加到server部分,這將會將緩存應用到所有的那些location中未指定自己的proxy_cache命令的服務中。

 

二、陳舊總比沒有強

NGINX內容緩存的一個非常強大的特性是:當無法從原始服務器獲取最新的內容時,NGINX可以分發緩存中的陳舊(stale,編者注:即過期內容)內容。這種情況一般發生在關聯緩存內容的原始服務器宕機或者繁忙時。比起對客戶端傳達錯誤信息,NGINX可發送在其內存中的陳舊的文件。NGINX的這種代理方式,為服務器提供額外級別的容錯能力,並確保了在服務器故障或流量峰值的情況下的正常運行。為了開啟該功能,只需要添加proxy_cache_use_stale命令即可:

 
  1. location / {
  2. ...
  3. proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
  4. }

按照上面例子中的配置,當NGINX收到服務器返回的error,timeout或者其他指定的5xx錯誤,並且在其緩存中有請求文件的陳舊版本,則會將這些陳舊版本的文件而不是錯誤信息發送給客戶端。

 

三、緩存微調

NGINX提供了豐富的可選項配置用於緩存性能的微調。下面是使用了幾個配置的例子:

 
  1. proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
  2. use_temp_path=off;
  3. server {
  4. ...
  5. location / {
  6. proxy_cache my_cache;
  7. proxy_cache_revalidate on;
  8. proxy_cache_min_uses 3;
  9. proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
  10. proxy_cache_lock on;
  11. proxy_pass http://my_upstream;
  12. }
  13. }

配置解釋如下:

  1. proxy_cache_revalidate指示NGINX在刷新來自服務器的內容時使用GET請求。如果客戶端的請求項已經被緩存過了,但是在緩存控制頭部中定義為過期,那么NGINX就會在GET請求中包含If-Modified-Since字段,發送至服務器端。這項配置可以節約帶寬,因為對於NGINX已經緩存過的文件,服務器只會在該文件請求頭中Last-Modified記錄的時間內被修改時才將全部文件一起發送。

  2. proxy_cache_min_uses設置了在NGINX緩存前,客戶端請求一個條目的最短時間。當緩存不斷被填滿時,這項設置便十分有用,因為這確保了只有那些被經常訪問的內容才會被添加到緩存中。該項默認值為1。

  3. proxy_cache_use_stale中的updating參數告知NGINX在客戶端請求的項目的更新正在原服務器中下載時發送舊內容,而不是向服務器轉發重復的請求。第一個請求陳舊文件的用戶不得不等待文件在原服務器中更新完畢。陳舊的文件會返回給隨后的請求直到更新后的文件被全部下載。

  4. proxy_cache_lock被啟用時,當多個客戶端請求一個緩存中不存在的文件(或稱之為一個MISS),只有這些請求中的第一個被允許發送至服務器。其他請求在第一個請求得到滿意結果之后在緩存中得到文件。如果不啟用proxy_cache_lock,則所有在緩存中找不到文件的請求都會直接與服務器通信。

 

四、NGINX 如何決定是否緩存?

默認情況下,NGINX需要考慮從原始服務器得到的Cache-Control標頭。當在響應頭部中Cache-Control被配置為Private,No-Cache,No-Store或者Set-Cookie,NGINX不進行緩存。NGINX僅僅緩存GET和HEAD客戶端請求。你也可以參照下面的解答覆蓋這些默認值。

1、Cache-Control頭部可否被忽略? 
可以,使用proxy_ignore_headers命令。如下列配置:

 
  1. ocation /images/ {
  2. proxy_cache my_cache;
  3. proxy_ignore_headers Cache-Control;
  4. proxy_cache_valid any 30m;
  5. ...
  6. }

NGINX會忽略所有/images/下的Cache-Control頭。proxy_cache_valid命令強制規定緩存數據的過期時間,如果忽略Cache-Control頭,則該命令是十分必要的。NGINX不會緩存沒有過期時間的文件。

2、NGINX能否緩存POST 請求? 
可以,使用proxy_cache_methods命令:

 
  1. proxy_cache_methods GET HEAD POST;

3、NGINX 可以緩存動態內容嗎?

可以,提供的Cache-Control頭部可以做到。緩存動態內容,甚至短時間內的內容可以減少在原始數據庫和服務器中加載,可以提高第一個字節的到達時間,因為頁面不需要對每個請求都生成一次。

4、可以使用Cookie作為緩存鍵的一部分嗎? 
可以,緩存鍵可以配置為任意值,如:

 
  1. proxy_cache_key $proxy_host$request_uri$cookie_jessionid;

5、NGINX 如何處理字節范圍請求?

如果緩存中的文件是最新的,NGINX會對客戶端提出的字節范圍請求傳遞指定的字節。如果文件並沒有被提前緩存,或者是陳舊的,那么NGINX會從服務器上下載完整文件。如果請求了單字節范圍,NGINX會盡快的將該字節發送給客戶端,如果在下載的數據流中剛好有這個字節。如果請求指定了同一個文件中的多個字節范圍,NGINX則會在文件下載完畢時將整個文件發送給客戶端。 一旦文件下載完畢,NGINX將整個數據移動到緩存中,這樣一來,無論將來的字節范圍請求是單字節還是多字節范圍,NGINX都可以在緩存中找到指定的內容立即響應。

參考: 
NGINX其他優化

NGINX緩存使用官方指南

使用Nginx的proxy_cache緩存功能取代Squid[原創]

Nginx proxy cache官方解釋

為Nginx安裝清緩存模塊——優化nginx服務器性能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM