
💡 Jak zmniejszyć obciążenie serwera i przyspieszyć WordPress za pomocą Memcached
Strona na WordPress bez buforowania przypomina silnik, który rozgrzewa się na nowo przed każdymi światłami. Odwiedzający wchodzi na stronę, PHP składa ją od zera, odwołując się do bazy danych 30-60 razy. Dziesięciu odwiedzających jednocześnie, trzysta zapytań. Pięćdziesięciu, lawina, przy której serwer traci połączenie szybciej, niż zdążą Państwo dopisać polecenie w konsoli.
Problem nie leży w WordPress jako takim. Dynamiczne składanie stron domyślnie jest z definicji marnotrawne: tak działają prawie wszystkie CMS-y. Rozwiązanie sprawdzone latami eksploatacji na projektach high-load to obiektowe buforowanie w pamięci RAM za pomocą Memcached. Prawidłowo skonfigurowana warstwa Memcached przekształca serwer z dławiącego się już przy pięćdziesięciu jednoczesnych użytkownikach w maszynę, która obsługuje setki bez ani jednej drgniętej milisekundy opóźnienia odpowiedzi.
Przeanalizujemy pełny cykl konfiguracji: od instalacji demona po test obciążeniowy, który pokaże różnicę w liczbach. Wszystkie polecenia przetestowano na Ubuntu 22.04/24.04, AlmaLinux 9 i są kompatybilne z PHP 8.2-8.5.
💡 Szybki przegląd:
- Zainstaluj demona Memcached i powiąż go z localhost dla bezpieczeństwa
- Skompiluj rozszerzenie PHP memcached przez PECL pod swoją wersję PHP
- Podłącz plik object-cache.php od Automattic do katalogu wp-content
- Zainstaluj Batcache i skonfiguruj advanced-cache.php dla buforowania stron
- Sprawdź nagłówki odpowiedzi przez DevTools przeglądarki
- Uruchom test obciążeniowy przez k6 i porównaj wyniki przed i po
Czym jest Memcached i dlaczego jest potrzebny Państwa WordPressowi
Memcached to demon, który przechowuje dane i obiekty w pamięci RAM serwera. W przeciwieństwie do buforowania plikowego (WP Super Cache, W3 Total Cache, WP Rocket), które zapisuje gotowy HTML na dysk, Memcached działa poziom niżej: wyniki zapytań do bazy danych, złożone menu, widgety, ustawienia strony osiadają w RAM i są pobierane w mikrosekundy bez ponownego składania.
W praktyce obraz wygląda następująco. Typowa strona WordPress bez buforowania wykonuje 30-60 zapytań do MySQL. Przy 50 jednoczesnych odwiedzających baza danych otrzymuje od półtora do trzech tysięcy zapytań, a procesor ulega przeciążeniu. Memcached przechwytuje przeważającą większość tych zapytań na poziomie pamięci RAM: baza odpoczywa, procesor jest wolny, serwer odpowiada natychmiast.
Technicznie Memcached operuje parami klucz-wartość. Klucz to hash zapytania SQL, wartość to zserializowany wynik. Kiedy WordPress po raz kolejny składa tę samą stronę, najpierw pyta Memcached: „Czy jest taki klucz?" i prawie zawsze otrzymuje gotową odpowiedź bez żadnego odwołania do dysku.
Technologia pojawiła się w 2003 roku wewnątrz LiveJournal jako rozwiązanie problemu ogromnych obciążeń bazy danych. Dziś na Memcached opierają się WordPress.com, Wikipedia, Twitter i tysiące wysoko obciążonych projektów. Dojrzała, stabilna i przewidywalna, dokładnie to, czego potrzebuje produkcja.
Instalacja demona Memcached
Rozważymy dwa główne scenariusze: Ubuntu (22.04/24.04) z apt i AlmaLinux / Rocky Linux 9 z dnf. Proszę dostosować polecenia do swojej dystrybucji.
Na Ubuntu:
1 sudo apt update && sudo apt install memcached libmemcached-tools -y
Na AlmaLinux / Rocky Linux 9:
1 sudo dnf install memcached libmemcached -y
Po instalacji demon uruchamia się automatycznie. Proszę sprawdzić:
1 systemctl status memcached
Domyślnie Memcached nasłuchuje na porcie 11211 na wszystkich interfejsach sieciowych. To dziura w bezpieczeństwie: Państwa cache jest dostępny dla każdego, kto dotrze do tego portu z zewnątrz. Dlatego w pierwszej kolejności należy powiązać demona z localhost.
Proszę otworzyć plik konfiguracyjny (/etc/memcached.conf na Ubuntu, /etc/sysconfig/memcached na AlmaLinux) i upewnić się, że linia -l 127.0.0.1 jest obecna i nie jest zakomentowana. Proszę zrestartować demona:
1 sudo systemctl restart memcached
Kompilacja rozszerzenia PHP przez PECL
Sam demon nie przyspieszy WordPressa, potrzebny jest klient PHP, który nauczy PHP komunikować się z Memcached. Proszę zainstalować rozszerzenie memcached, uwaga: dokładnie memcached (z literą d), nie memcache. To drugie zostało usunięte z PHP począwszy od wersji 8.0 i nie powinno być używane.
Na Ubuntu najpierw proszę zainstalować narzędzia do kompilacji. Proszę podstawić swoją wersję PHP: php8.4-dev, php8.3-dev lub php8.2-dev:
1 sudo apt install php8.4-dev php-pear libmemcached-dev pkg-config make gcc -y
Następnie proszę skompilować rozszerzenie:
1 sudo pecl install memcached
Na AlmaLinux / Rocky Linux 9 zestaw jest podobny:
1 sudo dnf install php-devel php-pear libmemcached-devel make gcc -y 2 sudo pecl install memcached
Po kompilacji rozszerzenie należy zarejestrować w PHP. Proszę utworzyć plik INI:
1 echo "extension=memcached.so" | sudo tee /etc/php/8.4/mods-available/memcached.ini 2 sudo phpenmod memcached
Na AlmaLinux ścieżka będzie inna: /etc/php.d/memcached.ini.
Jeśli pracują Państwo w Plesk Obsidian, polecenie ponownego odczytu handlerów PHP po instalacji rozszerzenia:
1 plesk bin php_handler --reread
Proszę sprawdzić, czy rozszerzenie zostało załadowane:
1 php -m | grep memcached
Wynik powinien zawierać memcached. Jeśli jest pusty, proszę sprawdzić ścieżkę do pliku INI i zrestartować PHP-FPM: sudo systemctl restart php8.4-fpm.
Podłączenie WordPressa do Memcached
Demon jest zainstalowany, rozszerzenie PHP załadowane. Teraz trzeba podłączyć WordPressa do Memcached na poziomie aplikacji.
De facto standardem jest dziś oficjalny drop-in od Automattic: wp-memcached na GitHub. Piszą go ci sami deweloperzy, którzy utrzymują Batcache i WordPress.com, działa poprawnie z PHP 8.x (w tym z 8.4 i 8.5).
Proszę skopiować plik object-cache.php z repozytorium do folderu /wp-content/ Państwa witryny. WordPress automatycznie go wykryje i zacznie używać Memcached jako backendu pamięci podręcznej obiektów, bez dodatkowych wtyczek.
Jeśli port Memcached różni się od standardowego (11211), proszę dodać w wp-config.php:
1 $memcached_servers = array( 2 array( '127.0.0.1', 11211 ) 3 );
Buforowanie stron: Batcache
Pamięć podręczna obiektów to połowa sukcesu. Druga połowa to buforowanie gotowych stron HTML, aby PHP w ogóle nie uruchamiało się dla anonimowych odwiedzających. Tutaj do gry wchodzi Batcache, wtyczka od Automattic, która przechowuje wygenerowane strony w tym samym Memcached.
Zasada działania jest prosta. Odwiedzający wchodzi na stronę, Batcache sprawdza, czy w Memcached jest gotowa kopia HTML tej strony. Jeśli jest i nie wygasła, serwuje ją natychmiast, omijając cały łańcuch PHP i MySQL. Jeśli jej nie ma lub odwiedzający jest zalogowany, strona jest generowana na nowo i przy okazji zapisywana w pamięci podręcznej na potrzeby kolejnych wizyt.
Instalacja:
Proszę pobrać archiwum z wordpress.org, rozpakować je i wgrać plik advanced-cache.php do katalogu głównego /wp-content/. Następnie otworzyć wp-config.php i dodać linię włączającą buforowanie:
1 define( 'WP_CACHE', true );
Plik batcache.php proszę wysłać do /wp-content/plugins/ i aktywować wtyczkę w panelu administracyjnym.
Wewnątrz advanced-cache.php znajduje się kilkanaście ustawień pod komentarzami. Najbardziej przydatne: max_age (czas życia strony w sekundach, domyślnie 300, czyli 5 minut), seconds (odstęp między regeneracjami jednego adresu URL), unique (nie buforować oddzielnie różnych User-Agent). Dla większości witryn wartości domyślne są odpowiednie; proszę je zmieniać tylko wtedy, gdy rozumie Pan/Pani, po co to robi.
Ważny niuans: proszę się upewnić, że define( 'WP_CACHE', true ) znajduje się PRZED linią require_once ABSPATH . 'wp-settings.php' w wp-config.php. Jeśli umieści się ją po, buforowanie nie zostanie włączone, a WordPress po cichu to zignoruje.
Wideo: instalacja i konfiguracja od początku do końca
Teoria to podstawa, ale polecenia konsolowe lepiej raz zobaczyć. W tym wideo: pełny cykl konfiguracji obiektowego buforowania WordPress z Redis i Memcached, od instalacji demona po weryfikację rezultatu:
Sprawdzenie działania Memcached
Najlepszy test jest praktyczny. Proszę dodać niestandardowy nagłówek w advanced-cache.php, aby wizualnie widzieć, czy strona została dostarczona z bufora, czy wygenerowana na nowo.
Proszę znaleźć w advanced-cache.php linię:
1 var $headers = array();
Zamienić na:
1 var $headers = array( 'memcached' => 'activated' );
Teraz proszę otworzyć DevTools w przeglądarce (F12), zakładkę Network i kilkakrotnie odświeżyć stronę. W Response Headers pojawi się pole memcached: activated, co oznacza, że Batcache zadziałał i strona trafiła do klienta bezpośrednio z RAM.
Dodatkowy sposób: wiersz poleceń serwera. Proszę sprawdzić statystyki demona:
1 echo "stats" | nc 127.0.0.1 11211
W wynikach proszę szukać get_hits i get_misses. Jeśli get_hits rośnie przy odświeżaniu stron witryny w przeglądarce, Memcached prawidłowo dostarcza zbuforowane obiekty.
Testowanie obciążeniowe: liczby, a nie wrażenia
Prawdziwą wartość Memcached pokazuje pod obciążeniem. Oryginalny test na serwerze z 1 rdzeniem i 512 MB pamięci dał imponujący kontrast: bez Memcached serwer padł po 15 sekundach przy 50 jednoczesnych użytkownikach, z Memcached utrzymywał 400+ użytkowników przez 50 sekund bez żadnego błędu. To nie magia, a fizyka: gdy procesor nie zużywa taktów na ponowne składanie tych samych stron, obsługuje nowych odwiedzających.
Do samodzielnego testowania używa się dziś nowoczesnych narzędzi. Jedno z najwygodniejszych to k6 od Grafana (otwarte źródło, uruchomienie jedną komendą). Najprostszy test:
1 k6 run --vus 100 --duration 30s http://your-site.com/
100 wirtualnych użytkowników przez 30 sekund. Proszę porównać wyniki z wyłączonym Batcache (proszę zakomentować WP_CACHE) i z włączonym, różnica w liczbie udanych odpowiedzi i medianie opóźnienia będzie mierzona w rzędach wielkości.
Do szybkiego sprawdzenia bez instalowania oprogramowania sprawdzi się narzędzie webowe Loader.io, darmowy plan daje do 10 000 klientów w teście, co z nawiązką wystarczy dla większości stron.
Redis czy Memcached: co wybrać
Pytanie, które nieuchronnie się pojawia: dlaczego nie Redis? Oba to magazyny in-memory typu key-value, oba działają z WordPressem przez drop-iny. Krótka odpowiedź: do czystego cache'owania Memcached jest prostszy i szybszy, do wszystkiego innego, Redis.
Porównajmy co do istoty:
Kryterium | Memcached | Redis |
|---|---|---|
Model danych | Tylko stringi | Stringi, listy, zbiory, hashe, dane geo, pub/sub |
Wielowątkowość | Wszystkie rdzenie od razu po instalacji | Przeważnie jednowątkowy |
Trwałość | Brak (czysty in-memory) | RDB/AOF, zapis na dysk |
Ekosystem WordPressa | Automattic/wp-memcached + Batcache | Redis Object Cache (ponad 400 000 instalacji) |
Złożoność konfiguracji | Minimalna | Nieco wyższa |
Czyszczenie cache przy restarcie | Pełne (ale nagrzewa się w ciągu minut) | Można zachować |
Do cache'owania obiektów WordPressa stringowy key-value wystarcza z dużym zapasem. Zbędne typy danych Redis nie są tu potrzebne. Na operacjach get/set oba ogranicza przepustowość sieci, a nie procesor, przy pozostałych warunkach bez zmian jest parytet. Memcached wygrywa w wielowątkowości: wykorzystuje wszystkie rdzenie procesora od razu po instalacji, podczas gdy Redis zachowuje przeważnie architekturę jednowątkową.
Redis warto wybrać, jeśli równolegle przechowuje Pan/Pani sesje, kolejki zadań lub potrzebuje trwałości. Do zadania „przyspieszyć WordPressa i odciążyć bazę" Memcached daje rezultat szybciej i z mniejszą liczbą ruchomych części.
⁉️🤔 Częste pytania
Czy Memcached jest potrzebny na hostingu współdzielonym?
Na większości hostingów współdzielonych Memcached jest niedostępny: dostawcy nie dają dostępu do demona na poziomie serwera. Jeśli jednak Pana/Pani plan taryfowy obejmuje VPS lub serwer dedykowany, instalacja zajmuje 10-15 minut i daje jeden z najbardziej odczuwalnych przyrostów szybkości spośród wszystkich optymalizacji WordPressa. Proszę sprawdzić możliwości planu w panelu sterowania lub dopytać w dziale wsparcia hostingu.
Batcache czy WP Rocket, co jest lepsze?
WP Rocket to kombajn, który robi i cache stron (plikowy), i optymalizację CSS/JS, i leniwe ładowanie. Batcache to wąskie narzędzie właśnie do cache'owania stron w Memcached. Nie konkurują one, a uzupełniają się: Batcache działa na poziomie serwera i serwuje strony bez uruchamiania PHP, WP Rocket na poziomie aplikacji. W praktyce często używa się obu: Batcache dla anonimowych odwiedzających, WP Rocket do zaawansowanej optymalizacji.
Jak wyczyścić cache Memcached?
Najprostszy sposób to zrestartować demona:
sudo systemctl restart memcached. Cache wyczyści się całkowicie i zacznie nagrzewać od nowa przy kolejnych wizytach. Do punktowego czyszczenia proszę użyć wtyczki Query Monitor: pokazuje ona zawartość cache obiektów i pozwala czyścić pojedyncze klucze. Jest też wariant konsolowy:echo "flush_all" | nc 127.0.0.1 11211.
Dlaczego po instalacji object-cache.php strona nie przyspieszyła?
Najczęstsza przyczyna to niezaładowane rozszerzenie PHP. Proszę sprawdzić
php -m | grep memcached. Jeśli wynik jest pusty, proszę sprawdzić ścieżkę do pliku INI i zrestartować PHP-FPM. Druga częsta przyczyna:object-cache.phpnie został skopiowany do/wp-content/lub został skopiowany z błędem uprawnień (musi być czytany przez użytkownika, na którym działa PHP). Trzecia: demon Memcached nie jest uruchomiony,systemctl status memcached.
Czy Memcached koliduje z OPcache?
Nie, to różne poziomy. OPcache cache'uje skompilowany bajtkod PHP, przyspiesza uruchomienie samego interpretera. Memcached cache'uje dane aplikacji: wyniki zapytań do bazy. Działają one na różnych etapach przetwarzania żądania i doskonale się uzupełniają. Na produkcji zaleca się używanie obu.
Czy można używać Memcached na kilku serwerach?
Tak, to jeden z głównych scenariuszy. W konfiguracji
$memcached_serversmożna wymienić kilka adresów IP demonów Memcached, klient automatycznie rozdzieli klucze między nie. W WordPressie pilnuje tego drop-inobject-cache.php: obsługuje on pulę serwerów od razu po instalacji.
Czy instalować Memcached na Pana/Pani serwerze
Instalacja Memcached to nie panaceum, a jeden z najskuteczniejszych kroków w optymalizacji WordPressa. Jeśli strona działa na VPS lub serwerze dedykowanym i chce Pan/Pani, aby wytrzymała wielokrotny wzrost ruchu bez wymiany sprzętu, proszę instalować. Dziesięć do piętnastu minut pracy w konsoli i baza danych przestaje być wąskim gardłem.
Jeśli strona jest na hostingu współdzielonym bez dostępu do demona, proszę rozważyć Redis (jest on częściej udostępniany) lub cache plikowy przez WP Rocket. A jeśli jest Pan/Pani już na VPS, proszę otworzyć terminal i przejść kroki z szybkiego przeglądu powyżej. Rezultat zobaczy Pan/Pani już w pierwszym teście obciążeniowym.



