SSD Nodes Learn 🎉 VPS od $5.50/mies.
Przewodniki Matt ConnorAutor: Matt Connor

Konfiguracja Redis jako Object Cache w WordPress na VPS

Instrukcja konfiguracji Redis dla WordPress na własnym serwerze VPS. Dowiedz się, jak poprawnie ustawić bind do localhost, limit maxmemory oraz politykę usuwania danych.

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 temu kolejne żądanie odczytuje dane z Redis, zamiast ponownie odpytywać MySQL. WordPress posiada wbudowany mechanizm pamięci podręcznej obiektów, WP_Object_Cache, jednak działa on w pamięci PHP i jest usuwany po zakończeniu żądania. Plik typu drop-in zastępuje go rozwiązaniem 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 (page cache) i od tego rozróżnienia zależy, czy ten przewodnik będzie przydatny. Pamięć podręczna stron zapisuje 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 użytkowników. W momencie, gdy użytkownik się zaloguje, doda produkt do koszyka lub otworzy panel administracyjny, pamięć podręczna stron przestaje działać, a WordPress wykonuje pełne żądanie: bootstrap, wtyczki i zapytania. Pamięć podręczna obiektów obniża koszt takiego żądania. Jest to narzędzie przeznaczone dla ruchu, którego pamięć podręczna stron nie obsługuje: sesji zalogowanych użytkowników, koszyków, procesu płatności oraz wp-admin. W sklepie WooCommerce stanowi 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 na szybkości głównie dzięki pamięci podręcznej stron, a dodanie Redis zmienia w niej niewiele.

Jedno szczere zastrzeżenie przed rozpoczęciem: pamięć podręczna obiektów nie przyspiesza wolnego zapytania. Eliminuje ona jedynie powtarzanie zapytania, które już zostało wykonane. Pierwsze żądanie po wygaśnięciu cache'u jest w pełni obciążające, więc wtyczka wykonująca zapytanie bez indeksu nadal będzie je uruchamiać raz na cykl życia pamięci podręcznej.

Wymagania wstępne

  • Serwer VPS z systemem Linux, dostępem do powłoki oraz sudo. Panele sterowania nie są wymagane.
  • 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 krok posiada odpowiednik w panelu administracyjnym, jednak wersja wiersza poleceń jest szybsza.
  • Redis zainstalowany na tej samej maszynie co PHP. Celem jest minimalizacja opóźnień, a komunikacja sieciowa niweluje ten zysk.

Poniższe polecenia przygotowano dla systemu Ubuntu 24.04 z PHP 8.3 oraz użytkownikiem serwera WWW 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 ping

redis-cli ping powinien zwrócić PONG. Jeśli wyświetlony zostanie komunikat Could not connect to Redis at 127.0.0.1:6379: Connection refused, oznacza to, że serwer nie działa. W takim przypadku należy zapoznać się z systemctl status redis-server przed przejściem do dalszych kroków.

php-redis to PhpRedis, rozszerzenie C z repozytorium PECL. Jest ono szybsze niż Predis, który jest implementacją czysto w PHP, a wtyczka korzysta z niego automatycznie, jeśli jest obecne. PHP-FPM wczytuje rozszerzenia podczas uruchamiania, więc nowe rozszerzenie pozostaje niewidoczne do momentu restartu puli.

sudo systemctl restart php8.3-fpm
php -m | grep redis

Należy zachować ostrożność przy ostatniej weryfikacji: php -m wyświetla moduły PHP dla linii komend, podczas gdy FPM może wczytywać inny zestaw. Wiarygodnym testem jest diagnostyka samej wtyczki, opisana w dalszej części dokumentacji.

Według stanu na sierpień 2026, Ubuntu 24.04 dostarcza Redis w wersji 7.0.15, co jest wystarczające dla pamięci podręcznej obiektów. Jeśli wymagana jest nowsza wersja, Redis udostępnia 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 redis

Jeśli dystrybucja dostarcza Valkey, czyli fork powstały po zmianie licencji w 2024 roku, obsługuje on ten sam protokół i wszystkie poniższe instrukcje mają do niego zastosowanie bez zmian.

Ograniczenie dostępu do Redis poprzez powiązanie z interfejsem

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 yes

Następnie sprawdź, co faktycznie nasłuchuje, ponieważ plik konfiguracyjny to tylko deklaracja, a ss stanowi dowód.

sudo ss -lntp | grep 6379

127.0.0.1:6379 to pożądany stan. 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ż loopback TCP. W tym modelu 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 770

Wł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 ping

Polecenie to musi zwrócić PONG. 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 uruchomienia, dlatego restart jest niezbędny. Pozostaw TCP włączone do momentu potwierdzenia działania gniazda, aby błąd w konfiguracji nie odciął obu ścieżek dostępu jednocześnie.

Ile pamięci RAM 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, aż do wyczerpania zasobów systemowych, co skutkuje interwencją mechanizmu OOM killer. Zazwyczaj kończy on proces o największym zapotrzebowaniu na pamięć, którym na serwerze z WordPress często jest MySQL. Komenda journalctl -k | grep -i "out of memory" pozwala sprawdzić taki incydent już po fakcie, gdy witryna jest już niedostępna.

Należy wyjść od całkowitej ilości pamięci RAM i odjąć od niej niezbędne rezerwy. MySQL lub MariaDB rezerwuje innodb_buffer_pool_size oraz bufory dla każdego połączenia. PHP-FPM zużywa pm.max_children pomnożone przez rzeczywisty rozmiar rezydentny jednego procesu roboczego, co w przypadku witryn z wieloma wtyczkami 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ęść przypada na Redis.

Przykładowy budżet dla VPS 4 GB obsługującego jeden sklep

Poniższe wartości są przykładowe i nie pochodzą z Twojego serwera. Należy zastąpić je wartościami raportowanymi 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. Zapewnia ona odpowiedni margines bezpieczeństwa, 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 dbsize

Jeśli used_memory_human utrzymuje się znacznie poniżej limitu, należy go obniżyć i przekazać odzyskaną pamięć RAM dla MySQL, który wykorzysta ją efektywniej. Jeśli użycie stale osiąga limit, a evicted_keys rośnie przez cały dzień, należy limit zwiększyć. Wartość tę ustawia się w /etc/redis/redis.conf.

maxmemory 256mb
maxmemory-policy allkeys-lru

redis-cli config set maxmemory 256mb wprowadza zmianę natychmiast, ale ustawienie to zostanie utracone po restarcie, co jest pułapką podobną do użycia samego sysctl -w. Należy edytować plik, następnie sudo systemctl restart redis-server i odczytać wartość ponownie. Warto zastosować drugie zabezpieczenie: limit MemoryMax w jednostce systemd zapobiega sytuacji, w której błędnie skonfigurowany Redis doprowadzi do awarii całego serwera. Limit ten należy ustawić powyżej maxmemory, nigdy na tym samym poziomie, ponieważ limit cgroup powoduje natychmiastowe zakończenie procesu zamiast usuwania kluczy. Jeśli Redis działa w kontenerze obok WordPress, tę samą wartość należy umieścić w limitach pamięci w pliku Compose, a ta sama logika decyduje o wyborze uruchomienia bazy danych w Docker lub bezpośrednio na hoście.

Świadomy wybór polityki usuwania danych

Domyślną wartością w nowej instalacji Redis jest noeviction. Sprawdź bieżące ustawienie:

redis-cli config get maxmemory-policy

W 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 to 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 ponownie pobiera dane z bazy, a następnie przy kolejnym żądaniu próbuje je zapisać i znów otrzymuje błąd. Serwis wykonuje teraz całą pierwotną pracę z bazą danych oraz dodatkowe zapytanie do Redis dla każdego klucza. W panelu administracyjnym WordPressa nie ma żadnej informacji o tym zjawisku. Komunikat pojawia się w dzienniku błędów PHP, dlatego należy użyć polecenia grep dla OOM command not allowed, gdy serwis zwalnia po wdrożeniu pamięci podręcznej.

allkeys-lru jest tutaj 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ś tego nie zauważy.

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 odmowy zapisu. allkeys-lfu jest 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 odnotuj powód tej decyzji.

Trwałość: wyłącz, chyba że masz powód

Dostarczony pakiet redis.conf włącza migawki RDB za pomocą linii takich jak save 900 1 i pozostawia wyłączony plik append-only. W przypadku czystej pamięci podręcznej obiektów migawki nie przynoszą żadnych korzyści. Dane są z definicji możliwe do odtworzenia, a pamięć podręczna przywrócona z pliku sprzed dwudziestu minut zawiera nieaktualne wartości, którym WordPress zaufa.

Migawki generują również koszty. BGSAVE tworzy proces potomny (fork), a mechanizm copy-on-write powoduje, że zużycie pamięci może gwałtownie wzrosnąć podczas zapisu przez proces potomny. Na małym serwerze VPS objawia się to w dzienniku Redis:

Can't save in background: fork: Cannot allocate memory

oraz często ostrzeżeniem przy starcie, które informuje, że operacja 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, należy ustawić pusty harmonogram zapisu w /etc/redis/redis.conf, zrestartować usługę i potwierdzić, że wartość jest pusta.

save ""
sudo systemctl restart redis-server
redis-cli config get save

Trwałość należy zachować tylko wtedy, gdy ta sama instancja przechowuje dane, których nie można odtworzyć, takie jak kolejki zadań lub liczniki limitów zapytań (rate-limit). W takim przypadku należy rozdzielić te funkcje. Pamięć podręczna wymaga usuwania kluczy (eviction), natomiast trwałe dane wymagają ich zachowania, a maxmemory wraz z polityką usuwania dotyczy całej instancji, a nie pojedynczego indeksu bazy danych. Czystym rozwiązaniem jest uruchomienie dwóch instancji na dwóch gniazdach (sockets).

Instalacja wtyczki i zrozumienie mechanizmu drop-in

wp plugin install redis-cache --activate
wp redis enable
wp redis status

wp 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 umieszczonego 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 już zajęła 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 błędne 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.php

Usunię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

Dodaj poniższe wpisy 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:' );

Dla gniazda Unix należy ustawić schemat oraz ścieżkę. Host oraz port są w takim przypadku 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, wyrażone w sekundach. Nie jest to wymagane przy użyciu allkeys-lru i jest przydatne, gdy wymagane jest sztywne ograniczenie maksymalnego czasu przechowywania nieaktualnej wartości w pamięci podręcznej.

Jedna instancja Redis, wiele witryn: prefiksy i bazy danych

Redis domyślnie udostępnia szesnaście numerowanych baz danych, z których każda posiada jedną płaską przestrzeń kluczy. Dwie instalacje WordPress wskazujące na bazę danych 0 bez zdefiniowanego prefiksu zapisują klucze o tych samych nazwach w tej samej przestrzeni, co pozwala jednej witrynie na odczytanie opcji drugiej i serwowanie ich użytkownikom. Każdej witrynie należy przypisać unikalny prefiks.

define( 'WP_REDIS_PREFIX', 'shopA_prod:' );
define( 'WP_REDIS_DATABASE', 1 );

Prefiks separuje nazwy kluczy. Indeks bazy danych separuje przestrzenie kluczy, co ma znaczenie podczas operacji czyszczenia: opróżnienie jednego indeksu nie wpływa na pozostałe. Wtyczka dokumentuje również WP_REDIS_SELECTIVE_FLUSH, funkcję usuwającą wyłącznie klucze pasujące do danego prefiksu zamiast całej bazy danych, kosztem konieczności ich przeskanowania.

Prefiksy i indeksy nie separują pamięci. maxmemory oraz polityka usuwania kluczy (eviction policy) dotyczą instancji jako całości, dlatego obciążona witryna może usunąć klucze witryny o niskim ruchu, a żadna z nich nie zgłosi tego faktu. Witryny, które nie mogą na siebie wpływać, wymagają oddzielnych instancji Redis, z których każda posiada własny socket oraz własny limit pamięci.

Izolacja pamięci podręcznej środowiska staging od produkcyjnego

Witryna stagingowa zazwyczaj stanowi 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 stagingowego. Testowa cena lub zmieniona opcja pojawi się wówczas w witrynie produkcyjnej bez wdrożenia i bez śladu w logach.

Należy ręcznie przypisać unikalne wartości dla każdego środowiska. W pliku wp-config.php środowiska stagingowego:

define( 'WP_REDIS_PREFIX', 'shop_staging:' );
define( 'WP_REDIS_DATABASE', 5 );

Jeszcze lepszym rozwiązaniem jest zapewnienie środowisku stagingowemu 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 skryptu, pozostawiając plik drop-in na miejscu, co jest również najszybszą metodą sprawdzenia, 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 status

Najistotniejszym wierszem jest Drop-in. Wartość Drop-in: Valid oznacza, że WordPress poprawnie ładuje plik 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, czy panel administracyjny wskazuje stan poprawny. Wartość Status informuje o połączeniu, a Client wskazuje używane rozszerzenie; w tym miejscu należy potwierdzić użycie PhpRedis zamiast Predis.

Następnie należy odpytać bezpośrednio rdzeń WordPress, ponieważ nie polega on na informacjach raportowanych przez wtyczkę.

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 sprawdzić, czy klucze docierają do bazy z użyciem skonfigurowanego prefiksu.

redis-cli -n 0 dbsize
redis-cli -n 0 --scan --pattern 'shop_prod:*' | head

Wzrost wartości dbsize podczas nawigowania po witrynie stanowi dowód działania. Brak kluczy przy poprawnym pliku drop-in oznacza, że połączenie jest przerywane w tle lub używany prefiks jest inny niż oczekiwany.

Na koniec należy sprawdzić metryki 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); dokumentacja Redis zawiera odpowiedni wzór. Należy przy tym zachować dwie uwagi. Liczniki obejmują całą instancję od ostatniego restartu, więc sumują dane wszystkich witryn i aplikacji współdzielących serwer. Ponadto współczynnik tuż po wyczyszczeniu pamięci lub restarcie nie jest miarodajny, 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 do współczynników trafień lub liczby zapytań publikowanych przez firmy hostingowe. Dane te opisują ich witryny i zestaw wtyczek. Istotna jest wyłącznie wartość zmierzona samodzielnie, przed i po wdrożeniu, na stronie, której nie można obsłużyć z poziomu 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ć test z użyciem plików cookie dla zalogowanego użytkownika, kilkukrotnie, przy wyłączonej pamięci podręcznej (WP_REDIS_DISABLED), a następnie przy włączonej. Różnica stanowi ostateczny wynik.

Kiedy Redis spowalnia WordPress

Główną przyczyną 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ążająca zarówno bazę danych, jak i pamięć podręczną.

Drugą przyczyną jest Redis na innym hoście. WordPress wykonuje setki wywołań pamięci podręcznej obiektów w ramach jednego żądania. Jeśli żądanie wykonuje 500 wywołań, a każdy cykl komunikacji trwa 1 ms, oznacza to pół sekundy oczekiwania, którego nie byłoby przy użyciu lokalnego gniazda. Redis powinien znajdować się na tym samym serwerze lub w sieci prywatnej o opóźnieniach poniżej jednej milisekundy.

Trzecią przyczyną, powszechną w starszych witrynach, jest ogromna tabela opcji ładowanych automatycznie (autoloaded options). 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 ładowane automatycznie, więc starsze zapytanie dopasowujące tylko 'yes' zaniża wyniki w nowoczesnych instalacjach. Każda wartość powyżej megabajta stanowi problem, który 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 powolnych żądań: przenieś WP-Cron na systemowe zadanie cron przy okazji wykonywania tych prac.

Utrzymanie systemu

Wyczyść pamięć podręczną po wdrożeniu zmian w opcjach lub kodzie motywu za pomocą wp cache flush. Uruchom wp redis update-dropin po aktualizacji wtyczki, jeśli plik typu drop-in nie zaktualizował się automatycznie. Używanie przestarzałego pliku drop-in z nowszą wersją wtyczki często powoduje nieprzewidziane działanie. Monitoruj działający serwer za pomocą redis-cli --stat, co spowoduje wyświetlanie jednej linii danych na sekundę. Polecenie redis-cli monitor wypisuje każdą wykonywaną komendę i znacząco obciąża procesor na aktywnych instancjach, dlatego należy używać go tylko przez kilka sekund w celu odtworzenia problemu, a następnie przerwać działanie.

Ostatnią istotną wartością jest redis-cli info clients, która 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 nie zamyka ich poprawnie.

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 zasobożerne 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ć Redisowi dla WordPressa?

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 rezydujący jednego procesu PHP-FPM, a następnie odjąć kilkaset megabajtów na jądro systemu i serwer WWW. Redisowi należy przydzielić część pozostałej pamięci, a po dniu pracy sprawdzić used_memory_human w redis-cli info memory i dokonać korekty. Pojedyncza witryna WordPress zazwyczaj zajmuje kilkadziesiąt megabajtów, więc maxmemory o rozmiarze 256 MB jest hojnym początkiem 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żdym kluczu 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 witryn WordPress może współdzielić jeden serwer Redis?

Mogą, pod warunkiem zachowania ostrożności. Każdej witrynie należy nadać unikalny WP_REDIS_PREFIX, aby nazwy kluczy nie kolidowały, oraz oddzielny indeks WP_REDIS_DATABASE, aby czyszczenie jednej witryny nie usuwało danych drugiej. Współdzielona pozostaje pamięć: maxmemory i mechanizm usuwania kluczy dotyczą całej instancji, więc obciążona witryna może usunąć klucze witryny o mniejszym ruchu. Witryny, które nie mogą na siebie wpływać, wymagają oddzielnych instancji Redis z własnymi limitami.

Czy usunięcie wp-content/object-cache.php jest bezpieczne?

Tak. Jest to plik typu drop-in, a nie część rdzenia WordPressa. Jego usunięcie przywraca WordPressa do wbudowanej pamięci podręcznej działającej 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.