Nginx Open File Cache

Nginx 的 open_file_cache 相關配置能夠緩存靜態文件的元信息,在這些靜態文件被頻繁訪問時能夠顯着提高性能。nginx

被緩存的文件元信息包括:緩存

  • fd,文件被打開一次後,fd保留使用
  • size
  • path
  • last modified time

這裏有個配置示例:socket

open_file_cache max=64 inactive=30d;
open_file_cache_min_uses 8;
open_file_cache_valid 3m;

max=64 表示設置緩存文件的最大數目爲 64, 超過此數字後 Nginx 將按照 LRU 原則丟棄冷數據。性能

inactive=30d 與 open_file_cache_min_uses 8 表示若是在 30 天內某文件被訪問的次數低於 8 次,那就將它從緩存中刪除。spa

open_file_cache_valid 3m 表示每 3 分鐘檢查一次緩存中的文件元信息是不是最新的,若是不是則更新之。code

2 爲何只緩存文件元信息而不緩存文件內容?

這個問題的關鍵是 sendfile(2).it

Nginx 在 serve 靜態文件的時候用的是 sendfile(2), 固然前提是你配置了 sendfile on, sendfile(2) 直接在 kernel space 內傳輸數據,對比使用 read(2)/write(2) 省去了兩次 kernel space 與 user space 之間的數據拷貝。而同時這些被頻繁讀取的靜態文件的內容會被 OS 緩存到 kernel space。在這樣的機制下,咱們緩存中有文件的 fd 和 size,直接調用 sendfile(2) 就能夠了。io

若是要 Nginx 連內容一塊兒緩存,那就須要每次文件變化都要用 read(2) 將數據從 kernel space 複製到 user space,而後放在 user space,每次應答請求的時候再從 user space 複製到 kernel space 而後寫入 socket。比起前面的方式,這樣的方式毫無優勢。ast

3 在文件緩存更新週期內文件發生變化了會發生什麼?

上面提到的配置中,30 天無訪問丟棄,每 3 分鐘作一次信息有效性監測,咱們暫且把 3 分鐘叫作緩存更新週期。那在這 3 分鐘以內文件發生變化了會怎樣呢?class

3.1 文件被刪除

因爲 nginx 還持有原文件的 fd,因此你刪除此文件後,文件並不會真正消失, client 仍是能經過原路徑訪問此文件。即使你刪除後又新建了一個同名文件,在當前緩存更新週期內能訪問到的仍是原文件的內容。

3.2 文件內容被修改

文件內容被修改能夠分爲兩種狀況:

文件大小不變或增大
因爲 nginx 緩存了文件的 size 而且使用 這個緩存中 size 調用 sendfile(2),因此此種狀況的後果是:
  • 從文件開始到原 size 字節中的變化能夠被 client 看到。
  • 原 size 以後的內容不會被 sendfile(2) 發送,所以 client 看不到此部分內容。
文件大小減少
此種狀況下,因爲一樣緣由,nginx 在 HTTP Header 中告訴 client 文件大小仍是原來的尺寸,而 sendfile(2) 只能發送真正的文件數據,長度小於 HTTP Header 中設置的大小,因此 client 會等待到本身超時或者 Nginx 在 epoll_wait 超時後關閉鏈接。

4 如何設置?

  • 若是你的靜態文件內容變化頻繁而且對時效性要求較高,通常應該把 open_file_cache_valid 設置的小一些,以便及時檢測和更新。
  • 若是變化至關不頻繁的話,那就能夠設置大一點,在變化後用 reload nginx 的方式來強制更新緩存。
  • 對靜態文件訪問的 error 和 access log 不關心的話,能夠關閉已提高效率。
相關文章
相關標籤/搜索