1. 程式人生 > >NGINX的快取介紹(一)

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的請求始終快取在同一快取中。