Oszczędzające pamięć strategie czyszczenia pamięci podręcznej dla dużych witryn?

30

Jedna z moich witryn Drupal 7 ma tysiące pól, kilka rodzajów treści, ponad 25 wyświetleń i setki (wkrótce tysiące) typów profili. Z tego powodu używam poprawki podstawowej, która lepiej buforuje informacje o polu encji (http://drupal.org/node/1040790), oraz wersji -dev widoków, która lepiej buforuje widoki poprzez wyświetlanie (zamiast posiadania OGROMNEGO wiersz pamięci podręcznej wyświetleń zawierający wszystkie dane wyświetleń).

Pomogło to załadować większość stron w witrynie przy użyciu 20-30 MB pamięci RAM zamiast 160 MB + (zamiast wyciągania wierszy tabeli cache_ * dla pól i widoków o wielkości 10 MB +, łatki pomagają utrzymać dane cache_ * znacznie bardziej wydajne).

Powoduje to jednak problem polegający na tym, że przebudowywanie pamięci podręcznej zajmuje naprawdę dużo czasu . Zwykle dłużej niż minutę lub dwie. W tym czasie Drupal po prostu nie ładuje żadnych stron (ponieważ pamięci podręczne, z których próbuje odczytać, nie zostały jeszcze zbudowane, inne żądania muszą czekać).

W cyklach o małym natężeniu ruchu nie jest to wielka sprawa; około stu użytkowników będzie musiało poczekać minutę, zanim strona się załaduje. Ale podczas cykli dużego ruchu serwer Apache zaczyna szaleć, z obciążeniem procesora większym niż 40, a pamięć szybko się zapełnia, ponieważ wszystkie wątki robocze czekają i maksymalnie obciążają pamięć, powodując zamianę. To rodzaj spirali śmierci. Ponowne uruchomienie httpd wyczyści wszystko, ale powrót do normalnego stanu zajmuje 5-10 minut.

Moim celem jest, aby czyszczenie pamięci podręcznej nie powodowało upadku witryny na kolana. Po pierwsze, jeśli korzystam z indywidualnych funkcji czyszczenia pamięci podręcznej admin_menu (takich jak „CSS i JS”, ​​następnie „Menu”, a następnie „Rejestr motywów” itp.), Wszystko pójdzie gładko, dopóki nie kliknę opcji „Strona i jeszcze”. To wtedy pamięć podręczna widoków jest resetowana (operacja bardzo intensywna pod względem procesora i bazy danych z liczbą widoków, które muszą być buforowane), a pamięć podręczna informacji o polu jest resetowana (która również wymaga dużej mocy obliczeniowej procesora i bazy danych w tej witrynie).

Więc ... moje pytania / pomysły:

  • Czy za pomocą drush i / lub innego skryptu powłoki mogę wyczyścić pamięć podręczną w bardziej inteligentny sposób niż „wysadzić wszystkie pamięci podręczne naraz i mieć nadzieję na czystą przebudowę”?
  • Czy mogę blokować żądania HTTP podczas czyszczenia pamięci podręcznej, aby apache nie był blokowany przez kilka żądań znaczników pamięci podręcznej?
  • Jeśli mogę wyczyścić pamięć podręczną poza żądaniem Drupal / normal httpd, prawdopodobnie mógłbym ustawić wyższy limit pamięci PHP dla operacji czyszczenia pamięci podręcznej i wycofać mój uniwersalny limit pamięci (teraz ustawiony na 256 MB, na wypadek, gdyby każdy wątek httpd musiał wyczyścić pamięć podręczną ...)

Zasadniczo: Czy istnieje jakiś inteligentny i pełen wdzięku sposób na wyczyszczenie wszystkich pamięci podręcznych za pomocą Drupala, oprócz zwykłego kliknięcia przycisku w interfejsie użytkownika lub użycia drush cc all?

[ Edytuj w celu wyjaśnienia : Głównym problemem, jaki mam, jest przebudowa pamięci podręcznej , która (a) zajmuje trochę czasu i (b) blokuje wszystkie pozostałe żądania do czasu zakończenia przebudowy. Chciałbym znaleźć sposób, aby to zrobić, aby odbudowy nie były tak zabójcze w czasach dużego natężenia ruchu.]

geerlingguy
źródło
2
Interesujące pytanie. Jeśli wyłączysz buforowanie, czy wydajność Twojej witryny jest wystarczająca? IOW, czy zoptymalizowałeś Apache / PHP / MySQL tak, aby działał tak samo, jak bez włączonego buforowania? Oczywiście nie widziałem twojego systemu, ale ustawienie apc.stat = 0 i upewnienie się, że masz wystarczającą ilość pamięci dla APC, pomoże zmniejszyć użycie dysku. Korzystanie z mysqltuner.pl daje również wskazanie, czy MySQL jest wąskim gardłem. Następnie możesz włączyć buforowanie i modyfikację (zwiększy to użycie DB, więc może być konieczne dostosowanie parametrów MySQL).
mpdonadio
Używam Redis (podobnego do memcache) do przechowywania tabel pamięci podręcznej widoków. To drastycznie poprawiło czasy ładowania. Z niecierpliwością oczekuję, że funkcja „pamięci podręcznej wyświetleń przez wyświetlanie” w stabilnym wydaniu ma sens.
uwe
@MPD - Wyłączenie buforowania szybko zabiłoby całą witrynę; zazwyczaj 100-500 uwierzytelnionych użytkowników, a niektóre sekcje witryny są dość ciężkie. Największym problemem dla mnie nie są odczyty pamięci podręcznej (w tym celu eksperymentowałem z pamięcią podręczną użytkowników Memcached, Redis i APC), ale z odbudową pamięci podręcznej, która wymaga dużego obciążenia procesora.
geerlingguy,
Idealnie chcesz użyć starych danych pamięci podręcznej podczas odbudowy nowej pamięci podręcznej. Czy to jest poprawne?
mikeytown2
@ mikeytown2 - poprawnie - to byłby idealny.
geerlingguy,

Odpowiedzi:

9

Czy istnieje jakiś inteligentny i pełen wdzięku sposób na wyczyszczenie wszystkich skrzynek za pomocą Drupala, oprócz zwykłego kliknięcia przycisku w interfejsie użytkownika lub użycia drush cc all?

Działania cache moduł robi. To zależy od reguły. Na przykład możesz ustawić regułę, aby wyczyścić określony widok, gdy węzeł typu „x” został dodany lub zaktualizowany. Zapoznaj się z dokumentami, aby uzyskać więcej informacji.

Spójrz także na moduł wdzięku pamięci podręcznej - jeszcze go nie wypróbowałem, ale wygląda interesująco.

uwe
źródło
Już używam drush cc [type]do specyficznego czyszczenia pamięci podręcznej (podobnej do akcji pamięci podręcznej), ale bardziej interesuje mnie znalezienie sposobów na bardziej przyjazne czyszczenie pamięci podręcznej i upewnienie się, że inne wątki httpd nie zabijają serwera Apache.
geerlingguy,
1
wygląda na to, że drush cc wyczyści wszystkie pamięci podręczne widoków. Za pomocą akcji pamięci podręcznej możesz po prostu wyczyścić określony widok lub wyświetlacz. Prawdopodobnie jest błąd w wersji Dev Views, w przeciwnym razie przebudowanie pamięci podręcznej nie zajmie ani minuty. Czy masz ten sam problem z widokami 7.x-3.5? Zobacz także drupal.org/project/cache_graceful - jeszcze nie próbowałem, ale wygląda interesująco
uwe
Program Views View dzieli wyświetlane widoki na własne wiersze pamięci podręcznej, aby pomóc w wydajności odczytu pamięci podręcznej. Oznacza to, że widoki spędzają prawdopodobnie 5 razy więcej czasu na budowaniu pamięci podręcznej (ale to pomaga zmniejszyć zużycie pamięci podczas bardzo częstego czytania pamięci podręcznej!).
geerlingguy,
Czy możesz dodać informacje o Cache Graceful do oryginalnej odpowiedzi? Zaakceptuję to, ponieważ ten konkretny moduł trochę pomaga (ale nie rozwiązuje problemu całkowicie dla mnie). Myślę, że będę musiał trochę przebudować witrynę, aby użyć mniejszej liczby pól i typów jednostek, aby naprawdę rozwiązać mój problem.
geerlingguy
dobrze. Chciałbym usłyszeć o twoich doświadczeniach z cache_graceful. Której części to nie naprawiło?
uwe
2

Głównym problemem jest to, że używasz MySQL do przechowywania danych w pamięci podręcznej - w przypadku witryn o wysokim obciążeniu jest to bardzo nieskuteczne rozwiązanie.

Radzę zamiast tego użyć Memcache . Zwiększy to znacznie wydajność systemu pamięci podręcznej i zapewni dwie wspaniałe korzyści:

  1. Pamięć podręczna jest znacznie szybsza dla operacji odczytu i zapisu, że MySQL - wszystkie operacje pamięci podręcznej (i pełna odbudowa pamięci podręcznej) będą działały szybciej.
  2. Ponieważ dane pamięci podręcznej nie są już przechowywane w DB - wyczyszczenie pamięci podręcznej nie zablokuje żadnych innych zapytań MySQL.

Oto przykład konfiguracji Memcache dla Drupala 7.

Eugene Fidelin
źródło
Używałem memcached i APC zarówno na różne sposoby, i chociaż w znacznym stopniu pomagają w odczytach pamięci podręcznej, głównym problemem, jaki mam, jest faktyczna przebudowa; baza danych prawie nic nie robi, gdy serwer WWW stempluje pamięć podręczną podczas (bardzo wolnego / długiego) procesu odbudowy.
geerlingguy
APC i Memcached tworzą różne rzeczy. Myślę, że poprawna konfiguracja Memcached pomoże ci. BTW, jeśli twoja strona jest najczęściej odwiedzana przez anonimowych użytkowników - możesz użyć Varnish. W takim przypadku Varnish użyje własnego systemu pamięci podręcznej, a Apache nie zostanie wykonany dla anonimowych żądań.
Eugene Fidelin,
Witryna ma prawie 100% uwierzytelniony ruch, w przeciwnym razie rozważę użycie Varnish. W tym momencie mogę zajrzeć do modułu Cache Graceful.
geerlingguy
0

Czy za pomocą drush i / lub innego skryptu powłoki mogę wyczyścić pamięć podręczną w bardziej inteligentny sposób niż „wysadzić wszystkie pamięci podręczne naraz i mieć nadzieję na czystą przebudowę”?

Jeśli nie chcesz wysadzić wszystkich skrzynek, użyj:, drush cc type_of_cacheaby wyczyścić konkretny lub zdefiniować własny.

Alternatywnie wyczyść ręcznie wszystkie tabele podobne do pamięci podręcznej, np

echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "DELETE FROM %;" | $(drush sql-connect) -v 

Jeśli używasz memcached (składnia Bash), spróbuj:

pgrep memcached && echo flush_all > /dev/tcp/127.0.0.1/11211

Czy mogę blokować żądania HTTP podczas czyszczenia pamięci podręcznej, aby apache nie był blokowany przez kilka żądań znaczników pamięci podręcznej?

Włącz tryb konserwacji ( drush -y vset maintenance_mode 1), aby uniemożliwić osobom dostęp do witryny. Lub skonfiguruj interfejs, aby przekierowywał gdzie indziej (np. W Varnish, przekierowywanie w Apache lub zmiana .htaccess).

Jeśli mogę wyczyścić pamięć podręczną poza żądaniem Drupal / normal httpd, prawdopodobnie mógłbym ustawić wyższy PHP memory_limitdla operacji czyszczenia pamięci podręcznej i wycofać mój uniwersalny memory_limit(teraz ustawiony na 256 MB, na wypadek, gdyby każdy wątek httpd musiał wyczyścić pamięć podręczną .. .).

Czyszczenie pamięci podręcznej nie zajmuje więcej pamięci, ale odbudowanie pamięci podręcznej po wyczyszczeniu zajmie więcej. Zawsze możesz rozgrzać pamięć podręczną, uruchamiając crona lub otwierając dowolną stronę, np

time php -n -d memory_limit=-1 time $(which drush) cc registry
PHP_OPTIONS='-d memory_limit="2G"' drush cron
php -d memory_limit=1G ./scripts/drupal.sh http://localhost/

Określ, -naby ignorować php.iniprzetwarzanie, które może dodatkowo przyspieszyć proces czyszczenia pamięci podręcznej.

kenorb
źródło
-1

Może to pociągać za sobą koszty pieniężne, ale możesz użyć konfiguracji serwera buforującego, takiego jak Varnish. Plusem jest to, że Varnish będzie obsługiwał twoją stronę, podczas gdy pamięć podręczna jest czyszczona na serwerze produkcyjnym, bez mądrzejszego użytkownika.

Wada: w zależności od liczby sekund / minut przestoju serwera produkcyjnego w porównaniu z ustawieniami limitu czasu VCL, Varnish może się zaktualizować w tym czasie i zobaczysz ekran błędu Varnish 503.

Ale to podejście wraz z Redis lub Memcache może pomóc.

Mulderjoe
źródło
To pytanie dotyczy tylko wewnętrznych pamięci podręcznych Drupal; odbudowanie pamięci podręcznej Drupala trwało wiecznie, a dodatkowe warstwy buforowania poza / przed Drupalem nie zrobiłyby wiele, aby pomóc w rzeczywistej odbudowie danych w pamięci podręcznej (oprócz odciążenia części ruchu, który serwer musiałby utrzymać przez pewien czas podczas buforowania są przebudowywane).
geerlingguy,
W takim przypadku zauważyłem, że Zend OpCache działa dobrze. :-)
mulderjoe,