Speicher sparende Cache-Löschstrategien für große Websites?


30

Eine meiner Drupal 7-Sites verfügt über Tausende von Feldern, eine Reihe von Inhaltstypen, mehr als 25 Aufrufe und Hunderte (bald Tausende) Profiltypen. Aus diesem Grund verwende ich einen Kern-Patch, der Entity-Feld-Informationen besser zwischenspeichert (http://drupal.org/node/1040790), und die -dev-Version von Views, die Ansichten besser nach Anzeige zwischenspeichert (anstatt nur einen RIESIGEN zu haben) Views-Cache-Zeile mit allen darin enthaltenen Views-Daten).

Dies hat dazu beigetragen, dass die meisten Seiten der Website mit 20 bis 30 MB RAM anstatt mit 160 MB RAM geladen wurden (anstatt cache_ * -Tabellenzeilen für Felder und Ansichten mit mehr als 10 MB aufzurufen, sorgen die Patches dafür, dass cache_ * -Daten effizienter bleiben).

Dies führt jedoch zu dem Problem, dass Cache-Neuerstellungen sehr lange dauern . In der Regel länger als ein oder zwei Minuten. Während dieser Zeit lädt Drupal einfach keine Seiten (da die Caches, aus denen es zu lesen versucht, noch nicht erstellt wurden, müssen andere Anforderungen warten).

In verkehrsarmen Zeiten ist dies keine große Sache. Etwa hundert Benutzer müssen lediglich eine Minute warten, bevor die Seite geladen wird. Bei Zyklen mit hohem Datenverkehr wird der Apache-Server jedoch mit einer CPU-Auslastung von über 40 verrückt, und der Arbeitsspeicher wird schnell voll, da alle Worker-Threads warten und ihren Arbeitsspeicher maximal ausnutzen, wodurch ein Auslagern verursacht wird. Es ist eine Art Todesspirale. Ein Neustart von httpd klärt die Dinge, aber es dauert 5-10 Minuten, bis die Dinge wieder normal sind.

Mein Ziel ist es, den Cache so zu löschen, dass die Site nicht in die Knie gezwungen wird. Wenn ich zum Beispiel die einzelnen Cache-Löschfunktionen von admin_menu verwende (wie "CSS und JS", dann "Menü", dann "Themenregistrierung" usw.), laufen die Dinge reibungslos, bis ich die Option "Seite und sonst" drücke. In diesem Fall wird der Cache der Ansichten zurückgesetzt (eine sehr CPU- und datenbankintensive Operation mit der Anzahl der Ansichten, die zwischengespeichert werden müssen), und der Feldinformationscache wird zurückgesetzt (der auf dieser Site auch CPU- und datenbankintensiv ist).

Also ... meine Fragen / Ideen:

  • Kann ich mithilfe von Drush- und / oder anderen Shell-Skripten die Caches intelligenter löschen als "alle Caches auf einmal sprengen und auf eine saubere Neuerstellung hoffen"?
  • Kann ich http-Anfragen blockieren, während der Cache geleert wird, damit der Apache nicht durch eine Reihe von Cache-Stamping-Anfragen verstopft wird?
  • Wenn ich Caches außerhalb von Drupal / normalen httpd-Anforderungen löschen kann, könnte ich vermutlich ein höheres PHP-memory_limit für den Cache-Clear-Vorgang festlegen und mein universelles memory_limit zurücksetzen (zurzeit auf 256 MB festgelegt, falls ein einzelner httpd-Thread Caches löschen muss) ...).

Grundsätzlich gilt: Gibt es eine intelligente und elegante Möglichkeit, alle Caches mit Drupal zu löschen, außer einfach auf die Schaltfläche in der Benutzeroberfläche zu klicken oder zu verwenden drush cc all?

[ Zur Klarstellung bearbeiten : Das Hauptproblem, das ich habe, sind Cache-Neuerstellungen , die (a) eine Weile dauern und (b) alle anderen Anforderungen blockieren, bis die Neuerstellungen abgeschlossen sind. Ich würde gerne einen Weg finden, es zu schaffen, damit die Umbauten in Zeiten mit hohem Verkehrsaufkommen nicht so tödlich sind.]


2
Interessante Frage. Wenn Sie die Zwischenspeicherung deaktivieren, ist die Leistung Ihrer Website ausreichend? IOW, haben Sie Apache / PHP / MySQL so optimiert, dass es auch ohne aktiviertes Caching läuft? Natürlich habe ich Ihr System nicht gesehen, aber wenn Sie apc.stat = 0 setzen und sicherstellen, dass Sie über genügend Arbeitsspeicher für APC verfügen, können Sie die Festplattennutzung reduzieren. Wenn Sie mysqltuner.pl verwenden, erhalten Sie auch einen Hinweis darauf, ob MySQL der Engpass ist. Dann können Sie das Caching und das Tweaken einschalten (dies erhöht die Datenbanknutzung, so dass Sie möglicherweise die MySQL-Parameter anpassen müssen).
mpdonadio

Ich verwende Redis (ähnlich wie Memcache), um die Views-Cache-Tabellen im Speicher zu halten. Das hat die Ladezeiten drastisch verbessert. Wir freuen uns darauf, dass die Funktion "Aufrufe nach Anzeige zwischenspeichern" in einer stabilen Version verfügbar sein wird. Das ist sehr sinnvoll.
Uwe

@MPD - Durch Deaktivieren der Zwischenspeicherung wird die gesamte Site schnell gelöscht. In der Regel 100-500 authentifizierte Benutzer, und einige Bereiche der Website sind ziemlich umfangreich. Das größte Problem für mich sind nicht die Cache-Lesevorgänge (ich habe dafür mit Memcached-, Redis- und APC-Benutzercache experimentiert), sondern der Cache-Neuaufbau, der sehr CPU-intensiv ist.
Geerlingguy

Idealerweise möchten Sie alte Cache-Daten verwenden, während der neue Cache wiederhergestellt wird. Ist das richtig?
mikeytown2

@ mikeytown2 - richtig - das wäre das ideale.
Geerlingguy

Antworten:


9

Gibt es eine intelligente und elegante Möglichkeit, alle Caches mit Drupal zu löschen, außer einfach auf die Schaltfläche in der Benutzeroberfläche zu klicken oder drush cc all zu verwenden?

Das Cache- Aktionsmodul erledigt das. Es kommt auf die Regel an. Beispielsweise können Sie eine Regel einrichten, um eine bestimmte Ansicht zu löschen, wenn ein Knoten vom Typ "x" hinzugefügt oder aktualisiert wurde. Weitere Informationen finden Sie in den Dokumenten .

Schauen Sie sich auch das Cache- Modul an, das noch nicht ausprobiert wurde, aber interessant aussieht.


Ich verwende bereits drush cc [type]für das Löschen des Caches (ähnlich wie bei Cache-Aktionen), bin jedoch mehr daran interessiert, Wege zu finden, um den Cache ordnungsgemäß zu löschen und sicherzustellen, dass andere httpd-Threads den Apache-Server nicht töten.
Geerlingguy

1
Es sieht so aus, als würde drush cc alle Views-Caches löschen. Mit Cache-Aktionen können Sie einfach eine bestimmte Ansicht oder Anzeige löschen. Es gibt wahrscheinlich einen Fehler in der Views-Dev-Version, ansonsten würde es nicht ein oder zwei Minuten dauern, um die Caches wiederherzustellen. Haben Sie das gleiche Problem mit Ansichten 7.x-3.5? Schauen Sie sich auch drupal.org/project/cache_graceful an - ich habe es noch nicht ausprobiert, aber es sieht interessant aus
zwar

Views dev unterteilt die View-Anzeigen in eigene Cache-Zeilen, um die Leseleistung im Cache zu verbessern. Dies bedeutet, dass Views wahrscheinlich das Fünffache des Zeitaufwands für das Erstellen des Cache-Speichers aufwenden (dies trägt jedoch dazu bei, die Speichernutzung beim Lesen von Caches erheblich zu reduzieren!).
Geerlingguy

Könnten Sie die Informationen zu Cache Graceful in Ihre ursprüngliche Antwort einfügen? Ich akzeptiere es, da dieses spezielle Modul ein wenig hilft (aber das Problem nicht vollständig für mich behebt). Ich denke, ich muss die Site ein wenig überarbeiten, um weniger Felder und Entitätstypen zu verwenden, um mein Problem wirklich zu beheben.
Geerlingguy

okay. Ich würde mich über Ihre Erfahrungen mit cache_graceful freuen. Welchen Teil hat es nicht behoben?
Uwe

2

Das Hauptproblem ist, dass Sie MySQL zum Speichern von Cache-Daten verwenden - für Websites mit hoher Auslastung ist dies eine sehr ineffektive Lösung.

Ich empfehle, stattdessen Memcache zu verwenden. Dies erhöht die Leistung des Cache-Systems erheblich und bietet Ihnen zwei große Vorteile:

  1. Memcache ist für Lese- und Schreibvorgänge viel schneller als MySQL - alle Cache-Vorgänge (und die vollständige Cache-Neuerstellung) funktionieren schneller.
  2. Da die Cache-Daten nicht mehr in der Datenbank gespeichert sind, blockiert das Löschen des Cache keine weiteren MySQL-Abfragen.

Hier ist ein Beispiel für die Memcache-Konfiguration für Drupal 7.


Ich habe sowohl memcached als auch APC auf verschiedene Arten verwendet, und obwohl sie beim Lesen des Cache sehr hilfreich sind, ist das Hauptproblem, das ich habe, die tatsächliche Neuerstellung. Die Datenbank tut so gut wie nichts, während der Webserver den Cache während des (sehr langsamen / langen) Wiederherstellungsprozesses stempelt.
Geerlingguy

APC und Memcached machen verschiedene Dinge. Ich denke, dass die richtige Konfiguration von Memcached Ihnen helfen wird. Übrigens, wenn Ihre Site hauptsächlich von anonymen Benutzern besucht wird, können Sie Varnish verwenden. In diesem Fall verwendet Varnish ein eigenes Cache-System und Apache wird nicht für anonyme Anfragen ausgeführt.
Eugene Fidelin

Die Site hat fast 100% authentifizierten Datenverkehr, ansonsten würde ich die Verwendung von Lack in Betracht ziehen. Ich könnte an dieser Stelle in das Cache Graceful-Modul schauen.
Geerlingguy

0

Kann ich mithilfe von Drush- und / oder anderen Shell-Skripten die Caches intelligenter löschen als "alle Caches auf einmal sprengen und auf eine saubere Neuerstellung hoffen"?

Wenn Sie nicht alle Caches sprengen möchten, verwenden Sie:, um drush cc type_of_cacheeinen bestimmten zu löschen, oder definieren Sie Ihren eigenen.

Alternativ können Sie alle cacheartigen Tabellen manuell löschen, z

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

Wenn Sie memcached (Bash-Syntax) verwenden, versuchen Sie Folgendes:

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

Kann ich http-Anfragen blockieren, während der Cache geleert wird, damit der Apache nicht durch eine Reihe von Cache-Stamping-Anfragen verstopft wird?

Aktivieren Sie den Wartungsmodus ( drush -y vset maintenance_mode 1), um zu verhindern, dass Personen auf die Site zugreifen. Oder konfigurieren Sie das Front-End so, dass es an eine andere Stelle umleitet (z. B. in Varnish, in Apache umleiten oder ändern .htaccess).

Wenn ich Caches außerhalb von Drupal / normalen httpd-Anforderungen löschen kann, könnte ich vermutlich ein höheres PHP memory_limitfür den Cache- memory_limitLöschvorgang festlegen und mein universelles zurücksetzen (zurzeit auf 256 MB festgelegt, falls ein einzelner httpd-Thread Caches löschen muss). .).

Das Löschen des Caches beansprucht nicht mehr Speicherplatz, aber das Wiederherstellen des Caches nach dem Löschen benötigt mehr Speicherplatz. Sie können die Caches jederzeit aufwärmen, indem Sie cron ausführen oder eine Seite öffnen, z

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/

Geben Sie -nan, dass die php.iniVerarbeitung ignoriert werden soll, wodurch der Cache-Löschvorgang zusätzlich beschleunigt werden kann.


-1

Möglicherweise sind damit Geldkosten verbunden, aber Sie können ein Caching-Server-Setup wie Varnish verwenden. Der Vorteil ist, dass Varnish Ihre Site bedient, während der Cache auf dem Produktionsserver geleert wird, ohne dass der Benutzer der Klügere ist.

Der Nachteil: Abhängig von der Anzahl der Sekunden / Minuten Ausfallzeit des Produktionsservers im Vergleich zu Ihren VCL-Timeout-Einstellungen wird Varnish möglicherweise während dieser Zeit aktualisiert und es wird ein Varnish 503-Fehlerbildschirm angezeigt.

Dieser Ansatz zusammen mit Redis oder Memcache kann jedoch hilfreich sein.


Diese Frage betrifft nur interne Drupal-Caches. Der Neuaufbau der Drupal-Caches hat ewig gedauert, und zusätzliche Cache-Ebenen außerhalb / vor Drupal würden nicht viel dazu beitragen, die eigentlichen Cache-Daten neu aufzubauen (abgesehen davon, dass ein Teil des Datenverkehrs, den der Webserver andernfalls für eine Weile im Cache halten müsste, abgeladen wird wieder aufgebaut werden).
Geerlingguy

In diesem Fall fand ich, dass Zend OpCache gut funktioniert. :-)
Mulderjoe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.