Konfiguracja Redis jako Object Cache w WordPress na VPS
Instrukcja konfiguracji Redis dla WordPress na własnym serwerze VPS. Dowiedz się, jak poprawnie ustawić maxmemory, politykę usuwania danych oraz jak zweryfikować działanie cache.
Rola pamięci podręcznej obiektów Redis w WordPress
Pamięć podręczna obiektów Redis dla WordPress przechowuje wyniki zapytań do bazy danych w pamięci RAM, dzięki czemu kolejne żądanie odczytuje je z Redis zamiast ponownie odpytywać MySQL. WordPress posiada wbudowaną pamięć podręczną obiektów w swoim jądrze, WP_Object_Cache, jednak działa ona w pamięci PHP i jest usuwana po zakończeniu żądania. Plik typu drop-in zastępuje ją mechanizmem komunikującym się z Redis, co pozwala na utrzymanie danych w pamięci pomiędzy kolejnymi żądaniami.
Pamięć podręczna obiektów to nie to samo co pamięć podręczna stron, a różnica ta decyduje o tym, czy ten przewodnik będzie przydatny. Pamięć podręczna stron przechowuje gotowy kod HTML adresu URL i serwuje go bez uruchamiania PHP. Jest to szybsze niż jakiekolwiek rozwiązanie oparte na Redis i sprawdza się w przypadku niezalogowanych odwiedzających. W momencie, gdy użytkownik się loguje, dodaje produkt do koszyka lub otwiera panel administratora, pamięć podręczna stron przestaje działać, a WordPress wykonuje pełne żądanie: bootstrap, wtyczki, zapytania. Pamięć podręczna obiektów sprawia, że takie żądanie jest mniej kosztowne. Jest to narzędzie przeznaczone do ruchu, którego pamięć podręczna stron nie obsługuje: sesje zalogowanych użytkowników, koszyki, proces finalizacji zamówienia, wp-admin. W sklepie WooCommerce jest to większość kosztownego ruchu.
Oba rozwiązania współpracują ze sobą i na obciążonej witrynie powinny być stosowane jednocześnie. Należy jasno określić, jaki problem jest rozwiązywany. Witryna wizytówkowa z anonimowymi czytelnikami zyskuje niemal całą wydajność dzięki pamięci podręcznej stron, a dodanie Redis niewiele zmienia.
Jedno uczciwe ograniczenie przed rozpoczęciem. Pamięć podręczna obiektów nie przyspiesza wolnego zapytania. Eliminuje ona powtarzanie zapytania, które już zostało wykonane. Pierwsze żądanie po wygaśnięciu cache ponosi pełny koszt, więc wtyczka wykonująca nieindeksowane zapytanie nadal uruchomi je raz na cykl życia pamięci podręcznej.
Wymagania wstępne
- Serwer VPS z systemem Linux, dostępem do powłoki oraz
sudo. Panel sterowania nie jest wymagany. - WordPress obsługiwany przez PHP-FPM, na przykład w ramach stosu LAMP na Ubuntu 24.04.
- Narzędzie WP-CLI zainstalowane na serwerze. Każdy opisany tu krok posiada odpowiednik w panelu administracyjnym, jednak wersja wiersza poleceń jest szybsza.
- Serwer Redis na tej samej maszynie co PHP. Kluczowym celem jest minimalizacja opóźnień, a przesyłanie danych przez sieć niweluje ten zysk.
Poniższe polecenia przygotowano dla systemu Ubuntu 24.04 z PHP 8.3 oraz użytkownikiem sieciowym www-data. Należy dostosować wersję PHP oraz nazwę użytkownika do konfiguracji własnego serwera. Polecenia wp należy wykonywać z poziomu katalogu głównego WordPressa, w którym znajduje się plik wp-config.php.
Instalacja Redis i rozszerzenia PHP
sudo apt update
sudo apt install -y redis-server php-redis
sudo systemctl enable --now redis-server
redis-cli pingredis-cli ping powinien odpowiedzieć PONG. Jeśli wyświetli Could not connect to Redis at 127.0.0.1:6379: Connection refused, serwer nie działa, więc przed kontynuowaniem przeczytaj systemctl status redis-server.
php-redis to PhpRedis, rozszerzenie C z PECL. Jest szybsze niż Predis, który jest czystym PHP, a wtyczka używa go automatycznie, gdy jest obecne. PHP-FPM ładuje rozszerzenia przy starcie, więc nowe rozszerzenie jest niewidoczne do momentu restartu puli.
sudo systemctl restart php8.3-fpm
php -m | grep redisZachowaj ostrożność przy ostatnim sprawdzeniu: php -m wyświetla moduły PHP dla linii komend, a FPM może ładować inny zestaw. Wiarygodnym sprawdzeniem jest diagnostyka samej wtyczki, opisana w dalszej części.
Według stanu na październik 2026, Ubuntu 24.04 dostarcza Redis 7.0.15, co jest wystarczające dla pamięci podręcznej obiektów. Jeśli wymagasz aktualnego wydania, Redis publikuje własne repozytorium APT.
sudo apt install -y lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update
sudo apt install -y redisJeśli Twoja dystrybucja dostarcza Valkey, fork powstały po zmianie licencji w 2024 roku, obsługuje on ten sam protokół, więc część tego przewodnika dotycząca WordPress działa w ten sam sposób. Nazwy na serwerze nie są tożsame. Pakiety Valkey w Debianie instalują valkey-server, valkey-cli, /etc/valkey/valkey.conf oraz jednostkę valkey-server.service, a nie redis-server, redis-cli ani /etc/redis/redis.conf. Na serwerze z Valkey zamień te nazwy w każdej poniższej komendzie i ścieżce, a przed przystąpieniem do konfiguracji gniazd odczytaj ścieżkę gniazda i użytkownika usługi z pliku konfiguracyjnego.
Ograniczenie dostępu do Redis
Domyślnie Redis nie wymaga hasła. Każdy podmiot, który nawiąże połączenie z portem 6379, może odczytać wszystkie wartości z pamięci podręcznej oraz wykonać FLUSHALL. Instancje wystawione na świat są wykrywane przez skanery w ciągu kilku godzin, dlatego konfiguracja sieci jest ważniejsza niż optymalizacja wydajności.
Otwórz /etc/redis/redis.conf i upewnij się, że poniższe linie są ustawione:
bind 127.0.0.1 -::1
protected-mode yesNastępnie sprawdź, co faktycznie nasłuchuje na portach, ponieważ plik konfiguracyjny to tylko deklaracja, a ss stanowi dowód.
sudo ss -lntp | grep 6379Oczekiwany wynik to 127.0.0.1:6379. Wartość 0.0.0.0:6379 oznacza, że Redis odpowiada na publicznym interfejsie: popraw linię bind i zrestartuj usługę.
Jeśli PHP i Redis znajdują się na tym samym serwerze, gniazdo Unix (Unix socket) jest lepszym rozwiązaniem niż pętla zwrotna TCP. W takim układzie stos TCP nie jest używany, a dostęp jest kontrolowany przez uprawnienia do plików, a nie przez reguły firewalla, które można przypadkowo zmienić.
unixsocket /run/redis/redis-server.sock
unixsocketperm 770Właścicielem gniazda jest użytkownik i grupa redis, dlatego użytkownik serwera WWW musi zostać dodany do tej grupy.
sudo systemctl restart redis-server
sudo usermod -aG redis www-data
sudo systemctl restart php8.3-fpm
redis-cli -s /run/redis/redis-server.sock pingPolecenie to musi zwrócić PONG. Wynik Could not connect to Redis at /run/redis/redis-server.sock: Permission denied oznacza, że zmiana grupy nie weszła w życie. Sprawdź id www-data i pamiętaj, że działający proces PHP-FPM zachowuje grupy przypisane w momencie startu, dlatego restart jest niezbędny. Pozostaw TCP włączone do czasu potwierdzenia działania gniazda, aby błąd w konfiguracji nie odciął obu ścieżek dostępu jednocześnie.
Ile pamięci należy przydzielić dla Redis?
Wartość tę należy wyznaczyć na podstawie zasobów własnego serwera. Redis bez ustawionego maxmemory zwiększa zużycie pamięci do momentu, aż jądro systemu wyczerpie dostępne zasoby i mechanizm OOM killer zakończy proces – zazwyczaj ten, który zajmuje najwięcej pamięci. Na serwerze z WordPress często jest to MySQL. Polecenie journalctl -k | grep -i "out of memory" pozwala sprawdzić taki incydent po fakcie, jednak w tym momencie witryna jest już niedostępna.
Należy zacząć od całkowitej ilości pamięci RAM i odjąć od niej wymagane zasoby. MySQL lub MariaDB rezerwuje innodb_buffer_pool_size oraz bufory dla każdego połączenia. PHP-FPM kosztuje pm.max_children pomnożone przez rzeczywisty rozmiar rezydentny jednego procesu roboczego, co w przypadku witryn z dużą liczbą wtyczek wynosi zazwyczaj od 64 MB do 128 MB. Jądro systemu oraz serwer WWW wymagają kilkuset megabajtów. Pozostała część to dostępny limit, z którego część otrzymuje Redis.
Przykładowy budżet dla VPS 4 GB obsługującego jeden sklep
Są to wartości przykładowe, a nie pomiary z Twojego serwera. Zastąp każdą z nich wartością raportowaną przez własną maszynę.
- MariaDB z buforem 1 GB: 1024 MB
- PHP-FPM, 10 procesów roboczych po 96 MB każdy: 960 MB
- Jądro, nginx lub Apache, sshd, logowanie: 512 MB
- Pozostała ilość: około 1.5 GB
Wartość maxmemory na poziomie 256 MB jest w tym przypadku rozsądnym punktem wyjścia. Pozostawia to realny zapas, a pojedyncza witryna WordPress rzadko potrzebuje więcej.
Teraz należy dokonać pomiarów zamiast zgadywać. Po dniu rzeczywistego ruchu:
redis-cli info memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli dbsizeJeśli used_memory_human utrzymuje się znacznie poniżej limitu, należy go obniżyć i przekazać pamięć RAM dla MySQL, który wykorzysta ją efektywniej. Jeśli wartość osiąga limit, a evicted_keys rośnie przez cały dzień, należy go zwiększyć. Wartość tę ustawia się w /etc/redis/redis.conf.
maxmemory 256mb
maxmemory-policy allkeys-lruredis-cli config set maxmemory 256mb stosuje się natychmiast, ale ustawienie to jest zapominane przy kolejnym restarcie – to ta sama pułapka, co w przypadku zwykłego sysctl -w. Należy edytować plik, następnie sudo systemctl restart redis-server, a potem sprawdzić odczytaną wartość. Warto zastosować drugie zabezpieczenie: limit MemoryMax w jednostce systemd zapobiega sytuacji, w której błędnie skonfigurowany Redis doprowadzi do awarii całego serwera. Należy ustawić go powyżej maxmemory, nigdy na równi, ponieważ limit cgroup kończy proces zamiast usuwać klucze. Jeśli Redis działa w kontenerze obok WordPress, ta sama wartość powinna znaleźć się w limitach pamięci w pliku Compose, a ta sama logika decyduje o wyborze uruchomienia bazy danych w Docker lub na hoście.
Świadomy wybór polityki eksmisji danych
Domyślną wartością w nowej instalacji Redis jest noeviction. Sprawdź bieżące ustawienie:
redis-cli config get maxmemory-policyW trybie noeviction pełna instancja przestaje akceptować operacje zapisu i zwraca następujący komunikat:
(error) OOM command not allowed when used memory > 'maxmemory'.Ten pojedynczy wiersz oznacza najgorszy scenariusz awarii w tym przewodniku, ponieważ serwis nie przestaje działać całkowicie. Staje się jedynie wolniejszy. Każdy zapis do pamięci podręcznej kończy się niepowodzeniem, więc WordPress odwołuje się do bazy danych w celu pobrania wartości, a następnie przy kolejnym żądaniu próbuje ponownie zapisać ją w Redis i znów otrzymuje błąd. Serwis wykonuje teraz całą pierwotną pracę z bazą danych oraz dodatkowe zapytanie do Redis dla każdego klucza. Żaden element panelu administracyjnego WordPress nie informuje o tym fakcie. Ciąg znaków pojawia się w dzienniku błędów PHP, dlatego należy użyć polecenia grep dla OOM command not allowed, gdy serwis zwalnia po dodaniu pamięci podręcznej.
allkeys-lru jest w tym przypadku właściwym ustawieniem domyślnym. Redis usuwa klucz, który był najdawniej używany, gdy kończy się pamięć, co jest pożądanym zachowaniem dla pamięci podręcznej obiektów, ponieważ każda wartość w niej zawarta jest kopią danych istniejących w MySQL. Utrata klucza kosztuje jedno zapytanie. Odmowa zapisu kosztuje każde zapytanie w każdym żądaniu, dopóki ktoś nie zauważy problemu.
Unikaj polityk volatile-* w tym zastosowaniu. Biorą one pod uwagę tylko klucze z ustawionym czasem wygaśnięcia, a dokumentacja Redis wskazuje, że zachowują się jak noeviction, gdy żaden klucz go nie posiada. WordPress przechowuje większość wpisów pamięci podręcznej obiektów bez TTL, więc volatile-lru w pamięci podręcznej obiektów może doprowadzić do zapełnienia pamięci i odrzucania zapisów. allkeys-lfu stanowi rozsądną alternatywę, jeśli ruch dotyczy często niewielkiego zbioru kluczy, ponieważ usuwa dane na podstawie częstotliwości, a nie czasu ostatniego użycia. Wybierz politykę świadomie i udokumentuj powód tej decyzji.
Trwałość: wyłącz, chyba że masz powód
Domyślna konfiguracja redis.conf dla Redis 7.0 pozostawia linię save zakomentowaną, co nie wyłącza migawek. Bez linii save, Redis korzysta z wbudowanego harmonogramu RDB: migawka po godzinie, jeśli zmienił się co najmniej jeden klucz, po pięciu minutach, jeśli zmieniło się 100, oraz po 60 sekundach, jeśli zmieniło się 10 000. Funkcja append-only file pozostaje wyłączona. Starsze poradniki cytują save 900 1, co było domyślnym ustawieniem Redis 6. Dla czystej pamięci podręcznej obiektów migawki nie dają żadnych korzyści. Dane są z definicji możliwe do odtworzenia, a pamięć podręczna przywrócona z pliku sprzed dwudziestu minut to zestaw nieaktualnych wartości, którym WordPress zaufa.
Migawki generują również koszty. BGSAVE forkuje proces, a mechanizm copy-on-write oznacza, że użycie pamięci może gwałtownie wzrosnąć, gdy proces potomny zapisuje dane. Na małym VPS objawia się to w dzienniku Redis:
Can't save in background: fork: Cannot allocate memoryoraz często ostrzeżeniem przy starcie, które informuje, że fork prawdopodobnie zakończy się niepowodzeniem w przyszłości:
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.Aby wyłączyć migawki, ustaw pusty harmonogram zapisywania w /etc/redis/redis.conf, zrestartuj usługę i potwierdź, że wartość jest pusta.
save ""sudo systemctl restart redis-server
redis-cli config get saveTrwałość zachowaj tylko wtedy, gdy ta sama instancja przechowuje dane, których nie można odtworzyć, takie jak kolejka zadań lub liczniki limitów zapytań. W takim przypadku rozdziel te dwie funkcje. Pamięć podręczna wymaga usuwania kluczy, a trwałe dane wymagają ich zachowania, natomiast maxmemory wraz z polityką usuwania dotyczy całej instancji, a nie pojedynczego indeksu bazy danych. Dwie instancje na dwóch gniazdach to czyste rozwiązanie.
Instalacja wtyczki i zrozumienie mechanizmu drop-in
wp plugin install redis-cache --activate
wp redis enable
wp redis statuswp redis enable wyświetla Object cache enabled. w przypadku powodzenia. W rzeczywistości polecenie to kopiuje wp-content/plugins/redis-cache/includes/object-cache.php do wp-content/object-cache.php. Ta kopia stanowi plik drop-in, który odpowiada za realizację zadania. WordPress wczytuje wp-content/object-cache.php na bardzo wczesnym etapie, jeszcze przed uruchomieniem kodu jakiejkolwiek wtyczki, dzięki czemu pamięć podręczna jest dostępna dla całego żądania. Aktywna wtyczka bez pliku drop-in nie buforuje żadnych danych.
Komunikaty o błędach wskazują, która część procesu uległa awarii. Object cache could not be enabled. oznacza, że kopiowanie nie powiodło się, ponieważ wp-content nie posiada uprawnień do zapisu dla użytkownika wykonującego WP-CLI. A foreign object cache drop-in was found. oznacza, że inna wtyczka buforująca zajęła już tę nazwę pliku; rozwiązaniem jest wp redis update-dropin. Komunikat kończący się Redis server is unreachable:, po którym następuje błąd klienta, oznacza nieprawidłowe ustawienia połączenia – należy wrócić do redis-cli ping.
Jeśli kopiowanie nie powiodło się z powodu uprawnień, należy umieścić plik ręcznie i nadać do niego uprawnienia użytkownikowi serwera WWW.
cp wp-content/plugins/redis-cache/includes/object-cache.php wp-content/object-cache.php
sudo chown www-data:www-data wp-content/object-cache.phpUsunięcie wtyczki nie powoduje usunięcia pliku drop-in. Najpierw należy uruchomić wp redis disable, co spowoduje wyświetlenie Object cache disabled. i usunięcie pliku. Usunięcie katalogu wtyczki przy pozostawionym pliku drop-in spowoduje, że witryna będzie nadal korzystać ze starego kodu buforowania bez wtyczki, która mogłaby go aktualizować.
Ustawienia połączenia w wp-config.php
Należy dodać je powyżej linii o treści /* That's all, stop editing! */, ponieważ stałe zdefiniowane po niej są inicjowane zbyt późno.
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );
define( 'WP_REDIS_PREFIX', 'shop_prod:' );W przypadku gniazda Unix należy ustawić schemat oraz ścieżkę. Host i port są wówczas ignorowane.
define( 'WP_REDIS_SCHEME', 'unix' );
define( 'WP_REDIS_PATH', '/run/redis/redis-server.sock' );
define( 'WP_REDIS_PREFIX', 'shop_prod:' );WP_REDIS_MAXTTL wymusza wygaśnięcie każdego klucza w sekundach. Nie jest to wymagane przy użyciu allkeys-lru, jednak opcja ta jest przydatna, jeśli wymagane jest sztywne ograniczenie maksymalnego czasu przechowywania wartości w pamięci podręcznej.
Jeden Redis, kilka witryn: prefiksy i bazy danych
Redis domyślnie udostępnia szesnaście numerowanych baz danych, a w każdej z nich jedną płaską przestrzeń kluczy. Dwie instalacje WordPress wskazujące na bazę danych 0 bez prefiksu zapisują te same nazwy kluczy w tej samej przestrzeni, więc jedna witryna może odczytać opcje drugiej i je serwować. Nadaj każdej witrynie własny prefiks.
define( 'WP_REDIS_PREFIX', 'shopA_prod:' );
define( 'WP_REDIS_DATABASE', 1 );Prefiks rozdziela nazwy kluczy. Indeks bazy danych rozdziela przestrzenie kluczy, co ma znaczenie przy czyszczeniu: opróżnienie jednego indeksu nie wpływa na pozostałe. Plik readme wtyczki wymienia również WP_REDIS_SELECTIVE_FLUSH, który czyści tylko klucze pasujące do prefiksu zamiast całej bazy danych, ale klasyfikuje tę stałą jako nieobsługiwaną opcję, która może przestać działać bez ostrzeżenia, ostrzegając jednocześnie, że skrypt Lua odpowiedzialny za to działanie jest wolny. Osobny indeks bazy danych dla każdej witryny to bezpieczniejszy sposób na odseparowanie operacji czyszczenia.
Prefiksy i indeksy nie rozdzielają pamięci. maxmemory oraz polityka usuwania dotyczą instancji jako całości, więc obciążona witryna może wypchnąć klucze mniej aktywnej witryny, a żadna z nich nie zgłosi tego faktu. Witryny, które nie mogą na siebie wpływać, wymagają oddzielnych instancji Redis, każda z własnym gniazdem i własnym limitem.
Izolacja pamięci podręcznej środowiska staging od produkcyjnego
Witryna typu staging jest zazwyczaj kopią plików i bazy danych środowiska produkcyjnego, co oznacza, że jest to kopia wp-config.php posiadająca ten sam prefiks oraz ten sam indeks bazy danych. Skierowanie jej na tę samą instancję Redis spowoduje nadpisanie kluczy produkcyjnych wartościami ze środowiska staging. Testowa cena lub zmieniona opcja pojawią się wówczas na działającej witrynie bez wdrażania zmian i bez pozostawienia śladu w logach.
Należy ręcznie przypisać unikalne wartości dla każdego środowiska. W pliku wp-config.php środowiska staging:
define( 'WP_REDIS_PREFIX', 'shop_staging:' );
define( 'WP_REDIS_DATABASE', 5 );Jeszcze lepszym rozwiązaniem jest zapewnienie środowisku staging własnej instancji Redis lub całkowita rezygnacja z pamięci podręcznej obiektów. Stała define( 'WP_REDIS_DISABLED', true ); wyłącza pamięć podręczną w czasie wykonywania, pozostawiając plik drop-in na miejscu, co jest również najszybszym sposobem na sprawdzenie, czy błąd wynika z działania pamięci podręcznej.
Starsze poradniki zalecają w tym celu ustawienie WP_CACHE_KEY_SALT. Plik readme wtyczki oznacza tę stałą jako przestarzałą i zastąpioną przez WP_REDIS_PREFIX, dlatego należy stosować nową nazwę.
Weryfikacja zamiast zaufania
Należy rozpocząć od diagnostyki wbudowanej w samą wtyczkę.
wp redis statusNajistotniejszą linią jest Drop-in. Wartość Drop-in: Valid oznacza, że WordPress ładuje plik tej wtyczki. Wartość Drop-in: Not installed oznacza, że kopiowanie nie powiodło się, a witryna nie posiada trwałej pamięci podręcznej, niezależnie od tego, jak poprawnie wygląda ekran administracyjny. Status raportuje połączenie, a Client wskazuje używane rozszerzenie; w tym miejscu należy potwierdzić, że jest to PhpRedis, a nie Predis.
Następnie należy zapytać bezpośrednio rdzeń WordPressa, ponieważ nie polega on na informacjach z wtyczki.
wp eval 'var_dump( wp_using_ext_object_cache() );'Wartość bool(true) oznacza, że rdzeń komunikuje się z zewnętrzną pamięcią podręczną obiektów.
Następnie należy potwierdzić, czy klucze docierają do celu z użyciem skonfigurowanego prefiksu.
redis-cli -n 0 dbsize
redis-cli -n 0 --scan --pattern 'shop_prod:*' | headWzrost wartości dbsize podczas nawigacji po witrynie stanowi dowód działania. Brak kluczy przy poprawnym pliku drop-in oznacza, że połączenie jest przerywane bez zgłaszania błędów lub używany jest inny prefiks, niż zakładano.
Na koniec należy sprawdzić dane pomiarowe dostarczane przez Redis.
redis-cli info stats | grep -E 'keyspace_hits|keyspace_misses|evicted_keys|expired_keys'Współczynnik trafień to keyspace_hits / (keyspace_hits + keyspace_misses), a dokumentacja Redis zawiera odpowiedni wzór. Należy go interpretować z dwoma zastrzeżeniami. Liczniki obejmują całą instancję od ostatniego restartu, więc sumują dane wszystkich witryn i aplikacji współdzielących ten zasób. Ponadto współczynnik tuż po wyczyszczeniu pamięci lub restarcie jest niemiarodajny, ponieważ pamięć podręczna jest w trakcie zapełniania. Należy pozwolić systemowi pracować przez pełny dzień z typowym ruchem.
Nie należy porównywać własnych wyników ze współczynnikami trafień lub liczbą zapytań publikowanymi przez firmy hostingowe. Dane te dotyczą ich witryn i zestawów wtyczek. Istotna jest wyłącznie własna wartość, zmierzona przed i po optymalizacji na stronie, której nie można obsłużyć z pamięci podręcznej strony (page cache).
curl -o /dev/null -s -w '%{time_starttransfer}\n' -b cookies.txt https://example.com/my-account/Należy wykonać ten test z użyciem plików cookie zalogowanego użytkownika, kilkukrotnie, przy wyłączonej pamięci podręcznej (WP_REDIS_DISABLED), a następnie przy włączonej. Różnica stanowi uzyskany wynik.
Kiedy Redis spowalnia WordPress
Głównym problemem jest pełna instancja z niewłaściwą polityką, omówiona powyżej: OOM command not allowed when used memory > 'maxmemory'. w dzienniku oraz witryna obciążona kosztami zarówno bazy danych, jak i pamięci podręcznej.
Drugim problemem jest Redis na innym hoście. WordPress wykonuje setki wywołań pamięci podręcznej obiektów w ramach jednego żądania. Jeśli żądanie generuje 500 wywołań, a każdy cykl komunikacji trwa 1 ms, oznacza to pół sekundy oczekiwania, którego nie byłoby w przypadku lokalnego gniazda. Redis powinien znajdować się na tej samej maszynie lub w sieci prywatnej o opóźnieniach poniżej milisekundy. Zysk z umieszczenia obu usług na tym samym serwerze w kontekście jądra systemu to odrębna kwestia: mechanizm cache aware scheduling wprowadzony w Linux 7.2 stara się utrzymywać procesy o dużej intensywności komunikacji, takie jak PHP-FPM i Redis, na rdzeniach współdzielących pamięć podręczną, jednak w środowisku VPS gość ma do tego mniejszy dostęp niż na sprzęcie typu bare metal.
Trzecim problemem jest ogromna tabela opcji ładowanych automatycznie (autoloaded options), co często zdarza się w starych witrynach. WordPress buforuje wszystkie opcje ładowane automatycznie jako jeden klucz, więc megabajt danych przesyłany jest przez połączenie przy każdym pojedynczym żądaniu. Należy to zmierzyć:
wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS kb FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on');"WordPress 6.6 wprowadził nowe wartości ładowania automatycznego, więc starsze zapytanie uwzględniające tylko 'yes' zaniża wyniki w nowoczesnych instalacjach. Jeśli łączna suma opcji ładowanych automatycznie przekracza megabajt, problem należy rozwiązać w tabeli opcji, a nie w Redis.
Restart czyści całą zawartość, więc minuty po systemctl restart redis-server to okresy samych chybionych trafień i pełnego obciążenia bazy danych. Restart należy przeprowadzać przy niskim natężeniu ruchu. Pamięć podręczna obiektów nie powstrzymuje również wp-cron.php przed uruchamianiem się podczas ładowania stron przez odwiedzających, co samo w sobie jest źródłem wolnych żądań: przenieś WP-Cron do rzeczywistego zadania system cron przy okazji wykonywania tych prac.
Utrzymanie systemu
Wyczyść pamięć podręczną po wdrożeniu, które zmienia opcje lub kod motywu za pomocą wp cache flush. Uruchom wp redis update-dropin po aktualizacji wtyczki, jeśli plik typu drop-in nie zaktualizował się automatycznie, ponieważ używanie starszego pliku drop-in z nowszą wersją wtyczki jest częstą przyczyną nietypowych błędów. Monitoruj działający serwer za pomocą redis-cli --stat, który wypisuje jedną linię na sekundę. redis-cli monitor wyświetla każde polecenie i obciąża procesor na intensywnie używanej instancji, dlatego należy go używać tylko przez kilka sekund podczas odtwarzania problemu, a następnie zatrzymać.
Ostatnia wartość, którą warto znać: redis-cli info clients raportuje connected_clients. PHP-FPM utrzymuje jedno połączenie na proces roboczy (worker), więc ta liczba powinna odpowiadać wartości pm.max_children i nie przekraczać jej o rząd wielkości. Jeśli tak się dzieje, oznacza to, że jakiś proces otwiera połączenia i ich nie zamyka.
FAQ
Czy nadal potrzebuję pamięci podręcznej stron (page cache), jeśli używam pamięci podręcznej obiektów Redis?
Tak, w przypadku ruchu anonimowego. Pamięć podręczna stron serwuje zapisany kod HTML bez uruchamiania PHP, co jest zawsze mniej kosztowne niż obsługa WordPressa z rozgrzaną pamięcią podręczną obiektów. Pamięć podręczna obiektów obsługuje żądania, które pamięć podręczna stron musi pominąć: zalogowanych użytkowników, koszyki, proces finalizacji zakupu oraz wp-admin. W przypadku sklepu lub serwisu członkowskiego warto korzystać z obu rozwiązań. Na stronie, której odwiedzający nigdy się nie logują, pamięć podręczna stron wykonuje niemal całą pracę.
Ile pamięci powinienem przydzielić dla Redis w WordPressie?
Wartość tę należy wyznaczyć na podstawie własnego serwera, zamiast kopiować gotowe liczby. Należy wziąć całkowitą ilość pamięci RAM, odjąć pulę buforów MySQL oraz bufory na połączenie, odjąć pm.max_children pomnożone przez rozmiar rezydentny jednego procesu PHP-FPM, a następnie odjąć kilkaset megabajtów na jądro systemu i serwer WWW. Należy przydzielić Redisowi część pozostałej pamięci, a po dniu pracy sprawdzić used_memory_human w redis-cli info memory i dokonać korekty. Pojedyncza strona WordPress zazwyczaj zajmuje kilkadziesiąt megabajtów, więc maxmemory o rozmiarze 256 MB jest bezpiecznym punktem wyjścia na serwerze z 4 GB RAM.
Dlaczego moja strona zwolniła po włączeniu pamięci podręcznej obiektów Redis?
Najczęstszą przyczyną jest zapełnienie instancji przy włączonej polityce noeviction. Redis odrzuca nowe zapisy i zwraca OOM command not allowed when used memory > 'maxmemory'., więc WordPress przy każdej wartości wraca do bazy danych, dodatkowo tracąc czas na niepotrzebne zapytanie do Redisa. Należy sprawdzić redis-cli config get maxmemory-policy, ustawić allkeys-lru i upewnić się, że maxmemory nie jest zbyt małe. Inne częste przyczyny to serwer Redis na zdalnym hoście, gdzie setki zapytań na jedno żądanie sumują się, oraz wielomegabajtowa opcja ładowana automatycznie (autoloaded options), która jest przesyłana przez połączenie przy każdym żądaniu.
Czy kilka stron WordPress może współdzielić jeden serwer Redis?
Mogą, pod warunkiem zachowania ostrożności. Należy nadać każdej stronie unikalny WP_REDIS_PREFIX, aby nazwy kluczy nie kolidowały ze sobą, oraz osobny indeks WP_REDIS_DATABASE, aby czyszczenie jednej strony nie usuwało danych innej. Współdzielona pozostaje pamięć: maxmemory i mechanizm usuwania kluczy dotyczą całej instancji, więc obciążona strona może usunąć klucze strony o małym ruchu. Strony, które nie mogą na siebie wpływać, wymagają osobnych instancji Redis z własnymi limitami.
Czy usunięcie pliku wp-content/object-cache.php jest bezpieczne?
Tak. Jest to plik typu drop-in, niebędący częścią rdzenia WordPressa, a jego usunięcie przywraca wbudowaną w WordPressa pamięć podręczną działającą w ramach pojedynczego żądania. Strona nadal działa, wykonując po prostu więcej zapytań do bazy danych. Zaleca się użycie wp redis disable, co usuwa plik w sposób czysty i zgłasza Object cache disabled.. Ręczne usunięcie pliku jest właściwym działaniem awaryjnym, jeśli Redis nie działa lub zachowuje się nieprawidłowo, a dostęp do panelu administratora jest niemożliwy.