Cache w Nginx

Jeżeli zależy nam na szybkim dostarczaniu treści powinniśmy rozważyć użycie statycznego cache. Rozwiązanie takie zmniejsza TTFB oraz obciążenie maszyny, na której stoi serwer treści dynamicznych, trzeba jedynie pamiętać, że niesie ze sobą pewne oczywiste ograniczenia jak np. opóźnienie pokazywania zmian na stronie.

Implementację statycznego cache w Nginx należy rozpocząć od przemyślenia gdzie będziemy składowali pliki wygenerowane na podstawie treści dynamicznych.  Umieszczanie tych plików na HDD jest oczywiście możliwe (i bez wątpienia przyspieszy czas wczytywania strony w porównaniu do jej generowania life), jednak w celu jeszcze większego przyspieszenia serwowania treści zalecane jest trzymanie plików cache w miejscach, do których dostęp jest na prawdę szybki.

Alternatywy dla rozwiązania tej kwestii są dwie:

  1. dysk SSD
  2. tmpfs w pamięci RAM

O ile uzyskanie dostępu do dysków SSD na wynajmowanych maszynach może być trudne (szczególnie w przypadku rozwiązań o niższym budżecie 😉 ) o tyle wygospodarowanie miejsca w RAM‚ie nie powinno być większym problemem.

Najpierw powinniśmy przygotować punkty montowania dla naszych tmpfs. Cache Nginx potrzebuje dwóch katalogów:

  • cache – w którym składowane są pliki statyczne oraz,
  • temp – który służy za bufor dla dużych zapytań do cache.

Przygotowujemy więc dwa punkty montowania. W mojej infrastrukturze umieściłem je tradycyjnie jako dwa katalogi w /mnt.

Następnie do naszych punktów montowania musimy przypisać tmpfs. Posłuży nam do tego komenda mount.

mount -t tmpfs -o size=300M tmpfs /mnt/nginx_cache
mount -t tmpfs -o size=212M tmpfs /mnt/nginx_temp

Oba katalogi montujemy jako osobny tmpfs, podając ich rozmiar, który uwzględnimy później w konfiguracji naszego cache.

Na koniec należy pamiętać o odpowiednim ustawieniu własności katalogów cache dla użytkownika Nginx (dla serwera instalowanego z paczek będzie to prawdopodobnie nginx:nginx ) oraz odpowiednich prawach dostępu.

Kiedy już przygotujemy miejsce dla naszego cache pora wprowadzić zmiany w konfiguracji samego Nginx. Niezbędne ustawienia musimy wprowadzić w dwóch sekcjach konfiguracji: http oraz server (dyrektywy z sekcji server mogą być oczywiście zdefiniowane globalnie w sekcji http, jednak ich definicja dla każdego z hostów jest w większości przypadków bardziej elastyczna).

W sekcji http definiujemy obligatoryjnie umiejscowienie naszego cache oraz katalogu temp,  a także jego rozmiar, preferowaną strukturę katalogów czy domyślny czas bezczynności:

   proxy_cache_path /mnt/nginx_cache levels=1:2 keys_zone=sample-cache:128m max_size=256m inactive=600m;
   proxy_temp_path /mnt/nginx_temp;

Składnia polecenia proxy_cache_path obejmuje zmienne:

  • levels – określającą liczbę poziomów podkatalogów w cache,
  • keys_zone – określającą nazwę strefy cache, do której odwoływać będziemy się m.in. w sekcji server oraz jej rozmiar,
  • max_size – określającą maksymalny rozmiar plików w cache, przy którym cache zostanie opróżniony,
  • inactive – określającą czas, po jakim nieaktywny element zostanie usunięty z cache.

W naszym przypadku wartości max_size oraz rozmiaru key_zone nie powinny być większe niż rozmiar zdefiniowanego dla cache tmpfs. Oczywiście w rozbudowanych konfiguracjach warto wykorzystać kilka stref cache o różnej strukturze katalogów i rozmiarze, wówczas ich sumaryczna wielkość nie może przekroczyć rozmiaru przydzielonego tmpfs.

Po zdefiniowaniu podstawowych wartości dla naszego cache pora przejść do jego wykorzystania na stronach. Rozpoczynamy od zdefiniowania do której z utworzonych wcześniej stref ma odwoływać się cache dla danej strony:

proxy_cache sample-cache;

Następnie definiujemy zachowanie cache dla poszczególnych kodów odpowiedzi z naszego serwera. Służą do tego dyrektywy:

  • proxy_cache_valid, o składni: proxy_cache_valid [kod odpowiedzi] [czas cache’owania treści ], która definiuje jak długo odpowiedzi danego typu mają być przechowywane w cache
  • proxy_cache_use_stale, która definiuje w jakich okolicznościach należy obligatoryjnie wygenerować zawartość cache ponownie

Przy definiowaniu ustawień cache można wykorzystać jeszcze dwie ciekawe dyrektywy. Pierwsza z nich – proxy_cache_key pozwala nam ręcznie określić schemat generowania kluczy – nazw poszczególnych elementów składowanych w cache. Jej użycie jest szczególnie przydatne, kiedy Nginx jest domyślnym proxy (działa w oparciu o konfigurację default dla wielu adresów, co opisywałem Serwer Nginx dla treści statycznych i dynamicznych ), a za proxy „stoi” np. kilka skryptów WordPress.  Nazwę kluczy możemy definiować przy pomocy standardowych lub własnych zmiennych Nginx np. tak:

proxy_cache_key "$scheme$host$request_uri";

Użycie dyrektywy proxy_cache_key pozwoli uniknąć sytuacji „nakładania” się różnych treści z cache pod tym samym kluczem, co z kolei mogłoby skutkować np. wyświetlaniem jednej strony głównej na wielu domenach.

Drugą przydatną dyrektywą jest proxy_cache_bypass. Pozwala ona określić nagłówek HTTP, w obecności którego strona zostanie wczytana z pominięciem cache:

proxy_cache_bypass $http_x_really_get_it;

Dyrektywę tę można wykorzystać do prostego  „wyłączania” cache dla poszczególnych podstron naszej strony. Wystarczy wówczas w kodzie strony umieścić uprzednio zdefiniowany nagłówek albo w sekcji serwer konfiguracji Ngnx z definicji ustawić wysyłanie odpowiedniego nagłówka dla niektórych adresów:

//wyłączanie cache dla zaplecza WordPress
if ($request_filename ~ "(wp-admin|wp-login)" ) {
     add_header X-Really-Get-It true;
}

Tak przygotowana konfigurację możemy już wdrażać na stronie.

Należy pamiętać, że przez zdefiniowany w konfiguracji czas strona nie będzie generowana z plików skryptów a pobierana z plików statycznych. Gdyby zaszła potrzeba szybkiego opróżnienia statycznego cache w naszym Nginx najlepiej skorzystać z narzędzi oferowanych przez Linux’a np.:

find [sciezka do cahe] -type f -delete
find [sciezka do tmp] -type f -delete

komendy te usuną pliki z katalogów cache pozostawiając jednocześnie ich strukturę.

Mikołaj Niedbała

I'm a Poland based IT administrator, linux administrator and IT engineer creating professional IT infrastructure solutions based on Linux and virtual environments.

2 thoughts to “Cache w Nginx”

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *