Nginx 的 open_file_cache 相關配置能夠緩存靜態文件的元信息,在這些靜態文件被頻繁訪問時能夠顯着提高性能。nginx
被緩存的文件元信息包括:緩存
這裏有個配置示例: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
這個問題的關鍵是 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
上面提到的配置中,30 天無訪問丟棄,每 3 分鐘作一次信息有效性監測,咱們暫且把 3 分鐘叫作緩存更新週期。那在這 3 分鐘以內文件發生變化了會怎樣呢?class
因爲 nginx 還持有原文件的 fd,因此你刪除此文件後,文件並不會真正消失, client 仍是能經過原路徑訪問此文件。即使你刪除後又新建了一個同名文件,在當前緩存更新週期內能訪問到的仍是原文件的內容。
文件內容被修改能夠分爲兩種狀況:
open_file_cache_valid
設置的小一些,以便及時檢測和更新。