Mentionsy Mentionsy
Rób WordPressa
Rób WordPressa

188 - Jak działa Object Cache w WordPressie i dlaczego Redis to game changer

30.10.2025 ·27 min 40 s · 1 rozdział · 1 sponsor

🎧 W tym odcinku rozbieram na czynniki pierwsze Object Cache w WordPressie - czym jest, jak działa i dlaczego Redis może diametralnie przyspieszyć Twoją stronę. Opowiadam też o prawdziwym przypadku z produkcji, gdzie niepoprawna konfiguracja Redisa spowodowała cofnięcie danych w WordPressie o… dwa tygodnie!Jeśli chcesz lepiej zrozumieć, jak działa cache w WordPressie i jak realnie przyspieszyć swoje projekty - ten odcinek jest właśnie dla Ciebie.🔧 Partnerem odcinka jest Cyberfolks - dostawca hostingu i domen idealnych pod WordPressa.

Rób WordPressa to podcast, w którym znajdziesz inspiracje, porady i rozmowy z ludźmi ze świata WordPressa. Cześć. W tym odcinku podcastu zajmiemy się tematem Object, Cache i Redisa w WordPressie. Zanim jednak przejdziemy do głównego tematu odcinka, krótka chwila dla partnera mojego podcastu marki Cyberfolks, która dostarcza domeny i hosting pod WordPressa. Partnerem dzisiejszego odcinka jest marka Cyberfolks. Twój ekspert od hostingu i domen. Jeśli szukasz hostingu dla swojej strony na WordPressie to polecam to miejsce. Pamiętaj, że z kodem podcast dostaniesz 20% rabatu na hosting WordPress. Jeśli pracujesz z WordPressem od jakiegoś czasu, no to myślę, że na pewno zetknąłeś się z takimi wtyczkami jak choćby WP Super Cache czy tym podobne wtyczki, które pozwalają na tzw.

0:20 · Cyberfolks 24

Page Cache, czyli cache'owanie całych stron WordPressa do statycznych plików HTML. Object Cache w WordPressie. Własnych rozwiązań. Dzisiaj przybliżę ci czym jest Object Cache, jak go wykorzystać, jak działa i co z tym wspólnego ma Redis. Zacznijmy od tego czym jest ten Object Cache w WordPressie. Jest to taki moduł WordPressa można powiedzieć Object Cache API, które dostarcza nam zestaw funkcji do tego, aby móc przechowywać w pamięci np.

No to potem jeśli w trakcie renderowania tej strony te informacje są gdzieś tam wykorzystywane. No to wtedy one już nie są pobierane z bazy danych, nie jest wykonywany żaden select na bazie danych, tylko WordPress korzysta z tego Object Cache'a i z tych danych, które pobrał gdzieś tam za pierwszym razem. Tylko problem jest taki, że właśnie w tym domyślnym trybie po zakończeniu requestu te dane znikają, bo ten cache jest trwały tylko w obrębie jednego requestu, czyli jeśli wchodzimy sobie na stronę główną, no to on się gdzieś tam buduje na początku i możemy go wykorzystać tylko podczas renderowania tej strony głównej. Z tego Object Cache API korzysta bardzo dużo o takich standardowych, wbudowanych funkcji, choćby takich odpowiadających za pobieranie danych użytkowników, jakichś metadanych, postów, czy opcji WordPressa z tabeli WP Options.

I żeby ten Persistent Object Cache nam działał w naszym WordPressie No to po pierwsze musimy mieć Redisa. Redis jest po prostu usługą, jest serwerem w obrębie danego hostingu, danej maszyny, serwera dedykowanego czy jakkolwiek macie to zorganizowane. I WordPress łączy się na odpowiednim porcie, można powiedzieć analogicznie jak do serwera bazy danych. Jest to po prostu usługa wystawiona gdzieś tam na hostingu, do której WordPress się łączy i korzysta z tego zamiast na przykład pytać bazę danych o jakieś tam rzeczy. Jaka jest zaleta tego Redisa? Redis jest trzymany w ramie, czyli dostęp do tych informacji jest bardzo szybki i co więcej on przechowuje dane na zasadzie klucz wartość. Te klucze są budowane oczywiście w taki sposób, żeby te dane były zawsze poprawne, żeby te klucze były unikalne, odpowiadały tam odpowiednim

Kryterium jeśli chodzi o unikalność czy po prostu dostęp do tych danych, bo możemy mieć taką sytuację, że mamy na przykład jakieś zapytanie do bazy danych, ale ono się różni jakimś tam jednym parametrem, no to oczywiście Redis musi wiedzieć, który wynik jest z którego zapytania, ale o to już dba WordPress, tym się nie musimy zupełnie przejmować. To jest już jakby poza nami, my sobie korzystamy tylko z tych funkcji odpowiadających właśnie za ustawienie tego cacha, pobranie czy wyczyszczenie. I dzięki temu, że Redis jest taką zewnętrzną usługą w stosunku do WordPressa, te dane są trzymane niezależnie od requestu jaki jest wykonywany do WordPressa. Przykładowo tabela opcji w WordPressie zmienia się raczej rzadko, bądź bardzo rzadko nawet.

I dzięki temu jeśli jeden request załaduje tą tabelę z bazy danych z MySQL do Redisa właśnie, no to przy następnych wejściach na stronę, nieważne czy ten sam użytkownik czy inny użytkownik, te dane już mogą być pobrane bezpośrednio właśnie z Redisa zamiast z bazy danych, co przekłada się na szybkość generowania strony, no bo te dane są dostępne po prostu szybciej. Są one skaszowane właśnie w Redisie. Jak działa Object Cache w WordPressie i dlaczego Redis to game changer. Najpopularniejszą wtyczką, która integruje nam WordPressa i potrafi zrobić ten Persistent Object Cache jest Redis Object Cache autorstwa Tila Krusa, bodajże tak to się czyta i tutaj mamy taką integrację.

Można powiedzieć na jedno kliknięcie. Tu jeszcze w zależności od tego jak ten Redis na danym hostingu jest skonfigurowany, czy jest na local hostie na standardowym porcie. No to albo działa nam od razu po zainstalowaniu, gdzie możemy włączyć sobie tą wtyczkę i on po prostu działa. Ewentualnie czasem musimy uzupełnić jakieś dane konfiguracyjne, jak choćby adres tego serwera Redis, czy ewentualnie jakiś customowy port, na którym ten Redis został uruchomiony na naszym hostingu. Po zainstalowaniu tej wtyczki WordPress po prostu z automatu będzie trzymał sobie te wszystkie dane, które trzyma w tym Object Cache standardowym, będzie je trzymał po prostu w Redisie, bądź w memcache, jeśli użylibyśmy Współczynnik procentowy.

A ile danych jest zaciąganych z bazy i zwykle ten współczynnik na takich powiedzmy standardowych WordPressach oscyluje gdzieś w okolicach 95%. Oczywiście mamy również zdecydowanie mniej zapytań do bazy danych. Jeśli mamy choćby query monitora zainstalowanego, to też zaraz zauważysz, że tych zapytań do bazy danych jest znacznie mniej, bo te dane są już trzymane właśnie w Redisie, a nie potrzeba odpytywać bazy danych. Efektem ubocznym instalacji tego Redisa jest również to, że transienty są trzymane zamiast w bazie danych, to właśnie też w tym Redisie i są wczytywane z Redisa, a nie z bazy danych. O transientach był już odcinek w moim podcaście, więc jeśli interesuje Cię ten temat, to możesz sobie do niego wrócić.

W zasadzie transienty są trochę podobnym mechanizmem do tego, Object Cache'u możemy sobie też zapisać jakąś wartość, jakiś wynik kostownego zapytania np. z określonym czasem ważności i w zasadzie po instalacji Redisa będzie to działało prawie tak samo jak ten Object Cache API. Jeśli nie mamy tego Redisa, no to Transienty są trwałe między poszczególnymi wykonaniami skryptu PHP-owego całego WordPressa. Pomiędzy requestami te dane są trwałe w Transientach. A tak jak już mówiłem wcześniej, w przypadku Object Cache są one trwałe, tylko po zakończeniu requesta znikają. No chyba, że podłączymy sobie Redisa, no to wtedy mamy ten Persistent Object Cache. I być może w tym momencie zadajesz sobie pytanie czy w zasadzie ten cały Redis ci jest potrzebny na twojej stronie czy na stronach które robisz.

Ogólnie rzecz biorąc jeśli masz tylko taką możliwość jeśli na hostingu ten Redis jest dostępny nie musisz za niego dopłacać czy aktywować jakiegoś tam wyższego pakietu. No to zdecydowanie polecam, bo można powiedzieć, że ma on same zalety. Nie wpływa jakoś tam negatywnie na pracę WordPressa, wręcz przeciwnie, przyspiesza ją. Szczególnie ważne będzie to na stronach, które nie za bardzo możemy scachować w taki klasyczny sposób za pomocą jakiegoś tam WP Super Cache czy podobnego pluginu czy np. Names mentioned in the video.

Czas ładowania się strony. Są bardziej wymagające, które wykonują jakieś tam dosyć skomplikowane operacje na bazie danych, czy właśnie wczytują duże ilości danych lub po prostu te bazy danych mają po kilka bądź kilkanaście gigabajtów. We wcześniejszym fragmencie tego odcinka powiedziałem o tym, że ten Redis jest praktycznie transparentny i przynosi same korzyści WordPressowi.

I faktycznie tak jest, jeśli wszystko działa i wszystko jest zrobione zgodnie ze sztuką. Natomiast może też powodować pewne dziwne problemy i jeden z takich problemów wydarzył się dosłownie tydzień albo dwa tygodnie temu. Był to bardziej mój błąd niż błąd Redisa, no ale jednak spowodował dosyć dziwne działanie jednej ze stron i nie do końca wiedzieliśmy skąd to działanie się bierze. Sytuacja była tego typu, że był to WordPress na serwerze, na jakiejś wirtualce w chmurze i tam oczywiście mieliśmy dostęp do roota, wszystko mogliśmy sobie konfigurować pod siebie tak jak potrzebowaliśmy. No i w pewnym momencie zainstalowałem tam Redisa po to, żeby przyspieszyć stronę, zoptymalizować właśnie też czas generowania tej strony i ograniczyć zapytania do bazy danych.

Instalacja Redisa na Linuxie to nie jest jakiś tam wielki wyczyn, powiedzmy kilka komend, sprawdzamy czy działa, działa, instalujemy wtyczkę do WordPressa, wszystko jest okej. No i tak sobie ten Redis tam działał. Potem pojawiły się jakieś dziwne problemy, że momentami on nie przyjmował połączeń. Tam doszedłem do tego, że prawdopodobnie przez to, że jak robił snapshoty Z ramu na dysk. No to wtedy coś tam się przycinało. Brakowało chyba ramu czy procesora na tym serwerze. No więc postanowiłem wyłączyć te snapshoty, bo w przypadku WordPressa były one zupełnie zbędne. Snapshoty to jest taki mechanizm, że po prostu Redis zrzuca z ramu, bo domyślnie on operuje tylko na pamięci RAM i zrzuca to po prostu z ramu do

Pliku na dysku, przez co może potem po restartcie odtworzyć ten stan taki jaki był przed restartem usługi czy przed np. wywaleniem się serwera. I domyślna konfiguracja właśnie zakładała, że takie snapshoty będą robione co ileś tam requestów chyba do Redisa. A tu akurat mieliśmy takie dosyć specyficzne wdrożenie, gdzie bardzo mocno była obciążona baza danych, bo tam, można powiedzieć, całą dobę szły jakieś procesy synchronizacyjne, które synchronizowały produkty W sklepie, z zewnętrznego systemu i przez to ta baza danych była dosyć intensywnie używana i ten Redis też bardzo często robił te zrzuty. Więc jak zauważyłem, że w logach gdzieś to są te problemy, no to zmieniłem konfigurację Redisa, żeby nie robił tych zrzutów, bo tak jak powiedziałem, są one zupełnie zbędne w kontekście WordPressa, a powodowały jakieś tam problemy i dodatkowy narzut, że serwer musiał jeszcze zapisywać te dane na dysk.

Zmieniłem ten config, sprawdziłem. Wszystko się zgadza. W logach nie widać tego, żeby Redis robił te zrzuty na dysk. Wszystko działa OK. No i tak sobie to działało, działało i jakiś czas później pojawiły się takie symptomy w tym WordPressie, tak jakbyśmy się cofnęli w czasie. Czyli mniej więcej tak, jakby ktoś przywrócił backup bazy danych, bo pojawiały się tam na przykład jakieś daty. O, jednym z takich dosyć ciekawych case'ów było to, że jeden z użytkowników zmienił sobie hasło i nie mógł się zalogować następnego dnia. Ale jak spróbował hasła, które miał ustawione tydzień czy dwa tygodnie wcześniej, no to wtedy już wszystko zadziałało prawidłowo. Pierwsze podejrzenia, no to ktoś gdzieś przywrócił jakiś backup bazy danych i przez to nam się to posypało.

To było dosyć naturalne podejrzenie i taki pierwszy kierunek jeśli chodzi o myślenie i szukanie problemów. Ktoś przywrócił pewnie backup i coś się sypnęło. No ale jak zaczęliśmy sobie tak analizować zawartość tej bazy danych, tam akurat na tej stronie był taki mechanizm, który logował jakieś tam cykliczne zadania, które wykonywał Cron i było to logowane w bazie danych. Jak popatrzyłem sobie po wykonaniach Po czasach wykonań poszczególnych zadań, no to tam była ciągłość. Nie było tam żadnego takiego symptomu na zasadzie, że mamy na przykład kilkudniową przerwę w logach, a te zadania były wykonywane dosłownie co kilkanaście minut, więc można powiedzieć bardzo często mieliśmy próbkowaną tą bazę danych i widziałem, że jednak Nie wskazuje nic na to, żeby ta baza była przywrócona i że gdzieś tam nam się te dane cofnęły w czasie, no ale mimo wszystko było to nawet potwierdzone screenami, że w pewnych momentach ten WordPress pokazywał jakieś stare daty, stare dane i nie do końca wiedzieliśmy skąd to się wzięło.

No a Redis jeśli widział ten snapshot w odpowiednim katalogu, no to niewiele myśląc ładował go przy każdym załadowaniu Redisa na nowo, czy przy każdym restarcie usługi. I tu się już dosyć szybko potem wyjaśniło, no nie dziwne, że na przykład Dane typu data, która była trzymana w tabeli wp-options cofała się o dwa tygodnie, no bo to był ten moment, w którym ten snapshot wykonał się po raz ostatni i Redis ładował to w tego pliku i w momencie, w którym WordPress pytał o tą opcję, no to nie odpytywał bazy danych, gdzie była poprawna data, tylko odpytywał Redisa i Redis zwracał właśnie tą datę tego snapshota. Podobnie było zresztą z tym hasłem użytkownika, po prostu w Redisie były zapisane dane tego użytkownika i ten snapshot był wykonany w momencie, gdy użytkownik miał jeszcze stare hasło, po czym po zmianie hasła on się mógł zalogować tam danego dnia, ale następnego dnia

Wczoraj był restart tego serwera, wczytał się ten zrzut z Redisa sprzed dwóch tygodni i z punktu widzenia WordPressa ten użytkownik miał stare hasło, mimo że w bazie się działo poprawne, no bo Redis jeśli ma tą informację w sobie, no to nie pobiera z bazy danych, tylko Po prostu sobie wczytuję tą wartość, która siedzi w tym Object Cache'u i WordPress widzi zupełnie inną wartość niż jest w bazie danych. Problem oczywiście się rozwiązał po usunięciu tego pliku ze Snapshotem. Redis startował wtedy z pustą bazą, jeśli była konieczność restartowania usługi. No i problem się więcej nie pojawił. Kolejnym częstym problemem z Object Cache'em, ogólnie z takimi mechanizmami właśnie bazującymi na Object Cache'u na Redisie,

Jest taki problem, że mimo tego, że w bazie ta wartość się zmienia, to WordPress widzi cały czas starą wartość. Natomiast to już nie wynika tak naprawdę z samego Object Cacha i z Redisa, tylko z nieprawidłowej implementacji przez programistów. I mam tu na myśli takie sytuacje, w której na przykład operujemy sobie na załóżmy polach postmeta danego wpisu, ale nie używamy tych standardowych WordPressowych funkcji. W tym przypadku przyczyna jest dosyć prosta. Podczas zwykłego takiego zapytania do bazy danych jest po prostu robiona operacja bezpośrednio na bazie danych z pominięciem tych wszystkich huków

Które się wykonują podczas użycia właśnie odpowiednich funkcji do operacji czy to na opcjach WordPressowych czy właśnie na polach meta, user meta, post meta i tak dalej. Jest po prostu to wykonywane z pominięciem, trochę tak jakbyśmy weszli do phpMyAdmin czy innego tego typu narzędzia. I zmienili sobie tą wartość bezpośrednio w bazie danych. No to WordPress nie będzie o tym wiedział, przez co nie będzie mógł wyczyścić tego cacha w Redisie, no bo domyślnie jeśli właśnie użyjemy jakiejś funkcji updateOptions, deleteOptions czy analogicznych dla pool postmeta. No to wtedy WordPress wie, żeby też w tym Redisie wyczyścić te wartości i załadować je na nowo ewentualnie. A jeśli to zrobimy gdzieś tam od boku, no to tak naprawdę Redis może nam zwracać zupełnie inne dane niż te, które są w bazie danych.

Tak jak już powiedziałem, zwykle to wynika po prostu z tego, że programista nie przewidział, że jeśli sobie zrobi tam jakąś operację za pomocą prostego zapytania do bazy, a nie odpowiednich funkcji WordPressowych, no to spowoduje taki problem, że ten Object Cache nie będzie zinwalidowany, przez co będzie zwracał często niepoprawne dane. To, co omówiłem do tego momentu, to jest sytuacja, w której po prostu instalujesz tą wtyczkę do WordPressa, podpinasz tego Redisa, który gdzieś tam sobie pracuje na twoim hostingu i twój WordPress ma lżej, po prostu wykonuje się szybciej, nie ma tego problemu z narzutem tych zapytań do bazy danych. Natomiast to jest też świetne narzędzie całe to Object Cache API. Jest to świetne narzędzie, które możesz wykorzystać przy pisaniu własnych pluginów czy własnych motywów.

No i naturalnie coś Redis musiałby wyrzucić z tego RAMu, żeby zwolnić sobie miejsce na nowe dane. No to tak to będzie działało, ewentualnie jeśli ustawimy sobie tam jakiś czas, no to ten cache będzie trzymany przez odpowiednią ilość sekund. WP Cache Get, no analogicznie do innych tego typu funkcji, jest to po prostu pobieranie tych danych, które zapisaliśmy za pomocą WP Cache Set, czyli WordPress zwraca nam dokładnie to, co zapisaliśmy sobie wcześniej w kodzie i WP Cache Delete usuwamy sobie to wszystko, co siedzi w tym Object Cache. I taki prosty przykład do czego można to użyć w swojej wtyczce. Załóżmy, że masz jakąś wtyczkę, która bazuje na własnych typach postów i na przykład wyświetlasz jakiś tam widget na stronie, czy gdzieś tam te informacje są wyświetlane, ale powiedzmy to zapytanie jest zbudowane z kilku warunków opartych o pola postmeta.

Co jak wiemy, w WordPressie nie jest najszybszą opcją na wyciąganie danych, no ale powiedzmy, że takie są wymagania biznesowe, ciężko to obejść, a był to najprostszy sposób na zaimplementowanie jakiegoś mechanizmu. No to używamy sobie tego Object Cache'a w ten sposób, że najpierw pobieramy sobie za pomocą wp-cache-get te dane, które powinny się znajdować w cache'u. Jeśli nie ma tych danych, no to oczywiście zwróci nam nula. W oparciu o to, potem sobie pobieramy te posty, wykonujemy to jedno skomplikowane zapytanie, które powiedzmy jest długie i czasochłonne i po pobraniu zapisujemy sobie to za pomocą funkcji wp-cache-set i potem przy kolejnych wywołaniach strony, jeśli zajdzie potrzeba wyciągnięcia tych danych, to już WordPress nie będzie odpytywał bazy danych, no bo funkcja wp-cache-get zwróci nam te dane i to zapytanie do bazy zostanie pominięte, no bo oczywiście powinniśmy sobie tam zaimplementować

Jakiegoś ifa, że jeśli nam nie zwrócił nic, no to pobierz z bazy, a jeśli zwrócił, no to przejdź dalej, na przykład do wyświetlenia tych postów. Mniej więcej tak to działa. Oczywiście w tym scenariuszu jeszcze będzie dosyć znaczącą rolę odgrywać ten czas wygasania cache'a. Możemy to ustawić na zero, czyli na to, żeby ten cache nie wygasał nigdy, ale musimy pamiętać o tym, że na przykład musimy podpiąć pod akcję save post odpowiednią funkcję, która będzie nam czyściła ten cache. Czyli jeśli zapisujemy sobie wynik jakiegoś tam zapytania do tego Object Cache'u, no to naturalnym jest to, że jeśli jakiś post się zmieni, no to powinniśmy wyczyścić ten Cache, żeby WordPress mógł wczytać te dane z bazy danych i zapisać sobie je w Redisie na nowo.

Oczywiście to był taki dosyć prosty przykład użycia tego Object Cache'a. Ja ostatnio optymalizowałem też bloki Gutenbergowe, które były napisane w skrajnie nieoptymalny sposób, bo miałem taki przykład bloku Gutenberga, który wyciągał właśnie dane z jakichś tam innych post-type'ów i ten blok wykonywał bodajże około 600 zapytań do bazy danych. W skrajnych przypadkach ten blog się generował po kilka, nawet kilkanaście sekund, bo tam były strasznie też nieoptymalne te zapytania do bazy i zrobiłem pewnego rodzaju obejście tego problemu na zasadzie takiej, że zapisywałem już wynikowego HTML-a do tego Object Cache'a. I do momentu, w którym te posty źródłowe, które zasilały tak naprawdę ten blog, się nie zmieniły, no to WordPress nie odpytywał bazy danych, nie wykonywał tych wszystkich skomplikowanych operacji tych pętli w pętli, tylko podawał już gotowego HTML-a, który zostałby renderowany za pomocą pierwszego requestu, tak naprawdę po zmianie tych danych w bazie danych.

Pokazano pierwszych 25 dopasowań — doprecyzuj frazę, aby zawęzić wyniki. Transkrypcja generowana automatycznie i niesprawdzana ręcznie — może zawierać błędy.