Wie lösche ich APC-Cache-Einträge?

170

Ich muss alle APC-Cache-Einträge löschen, wenn ich eine neue Version der Site bereitstelle. APC.php hat eine Schaltfläche zum Löschen aller Opcode-Caches, aber ich sehe keine Schaltflächen zum Löschen aller Benutzereinträge, aller Systemeinträge oder aller Verzeichniseinträge.

Ist es möglich, alle Cache-Einträge über die Befehlszeile oder auf andere Weise zu löschen?

lo_fye
quelle
1
Ich würde mich interessieren, wie abgelaufene Einträge gelöscht werden können! Sie können ein ttl angeben, aber php.net doc sagt, dass es bei der nächsten Anfrage gelöscht wird, wenn es abgelaufen ist ...
The Surrican

Antworten:

145

Sie können die PHP-Funktion verwenden apc_clear_cache.

Durch Aufrufen apc_clear_cache()wird der Systemcache geleert, und durch Aufrufen apc_clear_cache('user')wird der Benutzercache geleert.

Travis Beale
quelle
20
Ich entdeckte, dass Sie dazu über die Befehlszeile in apc.ini gehen und setzen müssen: apc.enable_cli = 1
lo_fye
51
lo_fye: Funktioniert das eigentlich? Nach meiner Erfahrung war die APC-CLI vollständig vom APC-Cache des Apache getrennt - und das zu Recht, da jeder CLI-Prozess in einem völlig separaten Prozess von Apache ausgeführt wird.
Frank Farmer
9
Frank Farmer: Ich bestätige, dass dies entweder mit Apache oder Nginx mit PHP 5.3.10 und der PHP-FPM-Schnittstelle funktioniert. Ich habe ein Shell-Skript erstellt, das diesen Befehl ausführtphp -r "apc_clear_cache();"
ezraspectre
13
Dies funktioniert NICHT, wenn Sie PHP mit mod_php ausführen. Aus dem Grund erklärte Frank Farmer.
David
11
Ich verwende Ubuntu Server 12.04 mit Nginx und PHP-FPM mit PHP Version 5.4. apc_clear_cache () und apc_clear_cache ('user') in der Befehlszeile löschen NICHT den APC-Cache des Webservers / der Webseiten !!!
Pieter Vogelaar
117

Ich glaube nicht, dass eine dieser Antworten tatsächlich dazu dient, den APC-Cache von der Befehlszeile zu löschen. Wie Frank Farmer oben kommentiert hat, wird die CLI in einem von Apache getrennten Prozess ausgeführt.

Meine Lösung für das Löschen über die Befehlszeile bestand darin, ein Skript zu schreiben, das ein APC-Löschskript in das kopiert web Verzeichnis zugreift und es dann löscht. Auf das Skript kann nur vom lokalen Host aus zugegriffen werden.

  1. apc_clear.php

    Dies ist die Datei, die das Skript in das Webverzeichnis kopiert, auf diese zugreift und sie löscht.

    <?php
    if (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')))
    {
      apc_clear_cache();
      apc_clear_cache('user');
      apc_clear_cache('opcode');
      echo json_encode(array('success' => true));
    }
    else
    {
      die('SUPER TOP SECRET');
    }
  2. Cache-Löschskript

    Dieses Skript kopiert apc_clear.php in das Webverzeichnis, greift darauf zu und löscht es dann. Dies basiert auf einer Symfony-Aufgabe. In der Symfony-Version wird die Symfony-Form zum Kopieren und Aufheben der Verknüpfung aufgerufen, die Fehler behandelt. Möglicherweise möchten Sie Überprüfungen hinzufügen, ob sie erfolgreich sind.

    copy($apcPaths['data'], $apcPaths['web']); //'data' is a non web accessable directory
    
    $url = 'http://localhost/apc_clear.php'; //use domain name as necessary
    $result = json_decode(file_get_contents($url));
    
    if (isset($result['success']) && $result['success'])
    {
      //handle success
    }
    else
    {
      //handle failure
    }
    
    unlink($apcPaths['web']);
Jeremy Kauffman
quelle
8
Sie können den Server auch einfach neu starten, z. B. Apache, wenn Sie mod_php verwenden, oder PHP FPM, wenn Sie dies verwenden. Ihre Lösung ist eleganter (kein Neustart des Servers erforderlich), aber komplexer :)
El Yobo
5
Dies ist besser als ein Neustart von php-fpm / apache, da Ihr Bereitstellungsbenutzer keinen Sudo-Zugriff haben muss. Wenn Sie auf mehreren Servern bereitstellen, kann es mühsam werden, das sudo-Kennwort für jeden Server einzugeben.
Andrew
Persönlich macht es mir nichts aus, das sudo-Passwort einzugeben (mein Bereitstellungsskript speichert das Passwort). Aber ich möchte Ausfallzeiten so weit wie möglich vermeiden. Deshalb bin ich daran interessiert, APC-Dateien zu leeren. Für Nginx gibt es eine (nicht so einfache) Möglichkeit, ohne Ausfallzeiten neu zu starten. Ich weiß es nicht für PGPfcgi, aber ich denke nicht. Verursacht das Spülen von APC Ausfallzeiten?
Julien
@andrew Sie können Ihren Benutzer so konfigurieren, dass er sudo verwendet, ohne Ihr Passwort einzugeben. Wenn das Löschen von APC alles ist, was es braucht, ist das in der Tat besser, wie Julien sagte.
ChocoDeveloper
1
@ Julien Ich denke, es kann die Serverlast erhöhen, wenn Sie CPU-intensive Ergebnisse oder etwas speichern. Ich würde es nicht zu Stoßzeiten tun.
ChocoDeveloper
68

Ich weiß, dass es nicht jedermanns Sache ist, aber: Warum nicht einen ordnungsgemäßen Neustart von Apache durchführen?

Zum Beispiel bei Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful
Tadas Sasnauskas
quelle
4
Ich weiß, dass dies nicht ideal ist, aber ich bin froh, dass Sie dies für eine schnelle und schmutzige Lösung erwähnt haben.
Bryan Petty
1
Es tut mir leid, dass ich diesen Thread erneut geöffnet habe, aber ich habe das gleiche Problem und frage mich, warum ein Cronjob einen anmutigen Neustart von Apache2 nicht ideal macht. Was sind einige der Nachteile dieses Ansatzes?
user2028856
@ user2028856 Es ist nichts falsch daran, außer dass einige möglicherweise nicht immer die volle Kontrolle über den Server haben. Also, wenn es für Sie funktioniert - verwenden Sie es.
Tadas Sasnauskas
@TadasSasnauskas Was meinst du mit "nicht immer die volle Kontrolle über den Server haben"? Ich meine, wird das Ausführen alle halbe Stunde oder so dazu führen, dass Apache abstürzt oder andere laufende Aktionen wie ein Cron-Backup abbricht?
user2028856
@ user2028856 Ich meinte, dass einige ihre Websites auf einem gemeinsam genutzten Server hosten könnten, ohne den Webserver neu starten zu können. Ein ordnungsgemäßer Neustart alle 30 Minuten sollte in Ordnung sein, da Sie keine Hintergrund-Worker über CLI mit aktiviertem APC ausführen (lange Rede, kurzer Sinn: In einigen Fällen kann es zu Kernel-Panik kommen)
Tadas Sasnauskas
29

Dies ist in der Dokumentation nicht angegeben, aber um den Opcode-Cache zu löschen, müssen Sie Folgendes tun:

apc_clear_cache('opcode');

BEARBEITEN: Dies scheint nur für einige ältere Versionen von APC zu gelten.

Unabhängig davon, welche Version Sie verwenden, können Sie den APC-Cache mod_php oder fastcgi nicht aus einem PHP-CLI-Skript löschen, da das CLI-Skript von einem anderen Prozess als mod_php oder Fastcgi ausgeführt wird. Sie müssen apc_clear_cache () innerhalb des Prozesses (oder des untergeordneten Prozesses) aufrufen, für den Sie den Cache leeren möchten. Die Verwendung von Curl zum Ausführen eines einfachen PHP-Skripts ist ein solcher Ansatz.

ColinM
quelle
1
Ich sollte hinzufügen, wenn Sie mod_php ausführen und den Cache über CLI-Modus PHP leeren möchten, können Sie dies nicht wirklich tun, da die beiden in unterschiedlichen Umgebungen ausgeführt werden. Meine Lösung bestand darin, dass sich der PHI-Modus im CLI-Modus mit file_get_contents über http aufruft. Hässlich, aber es funktioniert.
ColinM
Das Pipe'ing eines Dumps einer gültigen Fastcgi-Anfrage direkt an php-fpm mit netcat funktioniert ohne die Installation eines echten http-Servers, da der php-fpm-Server möglicherweise vom http one getrennt ist
baloo
Diese Antwort ist falsch. Wie in der Dokumentation erläutert, wird der Opcode-Cache immer gelöscht, wenn der angegebene Parameter! = 'User' ist.
Naitsirch
@naitsirch Vielleicht war dies ein Fehler, der in der neuesten Version behoben wurde. Als ich die Antwort veröffentlichte, funktionierte dies für mich. Leider weiß ich nicht, welche Version ich zu diesem Zeitpunkt verwendet habe, aber diese Antwort ist anscheinend für 25 andere Personen nützlich, die angeblich dieselbe Version wie ich verwendet haben. Die Dokumentation ist nicht immer korrekt und für ältere Versionen definitiv nicht immer korrekt.
ColinM
12

Wenn Sie den apc-Cache im Befehl löschen möchten: (verwenden Sie sudo, wenn Sie es benötigen)

APCu

php -r "apcu_clear_cache();" 

APC

php -r "apc_clear_cache(); apc_clear_cache('user'); apc_clear_cache('opcode');"
Léo Benoist
quelle
Ich erhalte eine solche Fehlermeldung auf meinem Terminal. Bitte helfen Sie mir. "Schwerwiegender PHP-Fehler: Aufruf der undefinierten Funktion apc_clear_cache () im Befehlszeilencode in Zeile 1"
RaviPatidar
1
Sie sollten testen, ob Ihr Apc ordnungsgemäß mit "php -m | grep apc" installiert ist
Léo Benoist
9

Wenn Sie auf einem NGINX / PHP-FPM-Stack arbeiten, ist es am besten, nur php-fpm neu zu laden

service php-fpm reload (oder was auch immer Ihr Reload-Befehl auf Ihrem System sein mag)

Passion4code
quelle
service php5-fpm reload ist das, was es funktioniert Ich überprüfte apc.php Statusdatei und Cache Status wurde zurückgesetzt Ich brauchte dies nach dem Hinzufügen der Option apc.stat = 0 zu php.ini
Salem
5

Wie im APC-Dokument definiert:

So löschen Sie den Cache-Lauf:

php -r 'function_exists("apc_clear_cache") ? apc_clear_cache() : null;'
codersofthedark
quelle
4

Eine andere Möglichkeit zur Verwendung der Befehlszeile, die noch nicht erwähnt wurde, ist die Verwendung von Curl.

Dies löst Ihr Problem nicht für alle Cache-Einträge, wenn Sie das Skript stock apc.php verwenden. Es kann jedoch ein angepasstes oder ein anderes Skript aufrufen, das Sie eingerichtet haben.

Dies löscht den Opcode-Cache:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=1&`date +%s`"

Ändern Sie den OB-Parameter in 3, um den Benutzercache zu löschen:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=3&`date +%s`"

Fügen Sie beide Zeilen in ein Skript ein und rufen Sie es mit $ PASSWORD in Ihrer Umgebung auf.

Andy Triggs
quelle
4

Wenn Sie die Ergebnisse über json überwachen möchten, können Sie diese Art von Skript verwenden:

<?php

$result1 = apc_clear_cache();
$result2 = apc_clear_cache('user');
$result3 = apc_clear_cache('opcode');
$infos = apc_cache_info();
$infos['apc_clear_cache'] = $result1;
$infos["apc_clear_cache('user')"] = $result2;
$infos["apc_clear_cache('opcode')"] = $result3;
$infos["success"] = $result1 && $result2 && $result3;
header('Content-type: application/json');
echo json_encode($infos);

Wie in anderen Antworten erwähnt, muss dieses Skript über http oder curl aufgerufen werden und Sie müssen gesichert sein, wenn es im Webstamm Ihrer Anwendung verfügbar ist. (per IP, Token ...)

Spule
quelle
3

apc_clear_cache () funktioniert nur mit derselben PHP-SAPI, für die der Cache geleert werden soll. Wenn Sie PHP-FPM haben und den APC-Cache löschen möchten, müssen Sie dies über eines der PHP-Skripte tun, NICHT über die Befehlszeile, da die beiden Caches getrennt sind.

Ich habe CacheTool geschrieben , ein Befehlszeilentool, das genau dieses Problem löst. Mit einem Befehl können Sie Ihren PHP-FPM-APC-Cache über die Befehlszeile löschen (er stellt für Sie eine Verbindung zu php-fpm her und führt APC-Funktionen aus).

Es funktioniert auch für Opcache.

Sehen Sie hier, wie es funktioniert: http://gordalina.github.io/cachetool/

Samuel Gordalina
quelle
2

Der Stall von APC hat die Möglichkeit, einen Cache in seiner Schnittstelle selbst zu löschen. Um diese Einträge zu löschen, müssen Sie sich bei der apc-Schnittstelle anmelden.

APC hat die Möglichkeit, Benutzername und Passwort in der Datei apc.php festzulegen.

Geben Sie hier die Bildbeschreibung ein

vinothvetrivel
quelle
Woher bekommen Sie diese Seite?
Pacerier
@Pacerier Sie erhalten diese Schnittstelle, wenn Sie ein php-apcPaket auf Ihrem System installiert haben .
Fremder
2

Wenn Sie fpm unter Ubuntu ausführen, müssen Sie den folgenden Code ausführen (aktiviert bei 12 und 14).

service php5-fpm reload
hrnsky
quelle
1

apc.ini

apc.stat = "1" zwingt APC, das Skript bei jeder Anforderung zu statisieren (zu überprüfen), um festzustellen, ob es geändert wurde. Wenn es geändert wurde, wird die neue Version neu kompiliert und zwischengespeichert.

Wenn diese Einstellung deaktiviert ist, wird APC nicht überprüft. Dies bedeutet normalerweise, dass der Webserver neu gestartet oder der Cache manuell geleert werden muss, um APC zu zwingen, Dateien erneut zu überprüfen. Beachten Sie, dass FastCGI-Webserverkonfigurationen den Cache beim Neustart möglicherweise nicht leeren. Auf einem Produktionsserver, auf dem sich die Skriptdateien selten ändern, können durch deaktivierte Statistiken eine erhebliche Leistungssteigerung erzielt werden.

mal
quelle
1

Die neue APC-Administrationsoberfläche bietet Optionen zum Hinzufügen / Löschen von Benutzercache und Opcode-Cache. Eine interessante Funktion ist das Hinzufügen / Aktualisieren / Löschen von Verzeichnissen aus dem OpCode-Cache

APC Admin-Dokumentation

Geben Sie hier die Bildbeschreibung ein

Jithin Jose
quelle
0

Eine gute Lösung für mich war, den veralteten Benutzercache nach der Bereitstellung einfach nicht mehr zu verwenden.

Wenn Sie jedem Ihrer Schlüssel ein Präfix hinzufügen, können Sie das Präfix beim Ändern der Datenstruktur von Cache-Einträgen ändern. Auf diese Weise erhalten Sie beim Bereitstellen das folgende Verhalten:

  1. Verwenden Sie keine veralteten Cache-Einträge, nachdem Sie nur aktualisierte Strukturen bereitgestellt haben
  2. Bereinigen Sie nicht den gesamten Cache bei der Bereitstellung, um Ihre Seite nicht zu verlangsamen
  3. Einige alte zwischengespeicherte Einträge können nach dem Zurücksetzen Ihrer Bereitstellung wiederverwendet werden (wenn die Einträge nicht bereits automatisch entfernt wurden).
  4. APC entfernt alte Cache-Einträge nach Ablauf ODER bei fehlendem Cache-Speicherplatz

Dies ist nur für den Benutzercache möglich.

mabe.berlin
quelle
0

Erstellen Sie die Datei APC.php

foreach(array('user','opcode','') as $v ){
    apc_clear_cache($v);
}

Führen Sie es in Ihrem Browser aus.

anshuman
quelle
2
Soweit ich weiß, wird die CLI-Instanz nicht dasselbe APC-Cache-Speichersegment gemeinsam nutzen, sodass nur ein leeres, isoliertes APC-Cache-Segment gelöscht wird.
AB Carroll
Abhängig von den Distributionen und Konfigurationen kann der APC-Cache ein separates Speichersegment haben. Ich habe es für eine allgemeinere Lösung aktualisiert.
anshuman
0

Meine Problemumgehung für Symfony-Build mit Beute von Instanzen auf demselben Server:

Schritt 1. Erstellen Sie einen Trigger oder etwas, um ein Dateiflag zu setzen (z. B. Symfony-Befehl), und erstellen Sie dann marker file..

file_put_contents('clearAPCU','yes sir i can buggy')

Schritt 2. Fügen Sie in der Indexdatei zu Beginn den Löschcode hinzu und entfernen Sie ihn marker file.

if(file_exists('clearAPCU')){
    apcu_clear_cache();
    unlink('clearAPCU');
}

Schritt 2. Führen Sie die App aus.

Ajsti.pl - Maciej Szewczyk
quelle
-1

Wir hatten ein Problem mit APC und Symlinks zu Symlinks zu Dateien - es scheint Änderungen in Dateien selbst zu ignorieren. Irgendwie half es, die Datei selbst zu berühren. Ich kann nicht sagen, was der Unterschied zwischen dem Ändern und Berühren einer Datei ist, aber irgendwie war es notwendig ...

jakub.lopuszanski
quelle