Comment effacer les entrées du cache APC?


170

Je dois effacer toutes les entrées du cache APC lorsque je déploie une nouvelle version du site. APC.php a un bouton pour effacer tous les caches d'opcode, mais je ne vois pas de boutons pour effacer toutes les entrées utilisateur, ou toutes les entrées système, ou toutes les entrées par répertoire.

Est-il possible d'effacer toutes les entrées du cache via la ligne de commande, ou d'une autre manière?


1
Je serais intéressé de savoir comment effacer les entrées expirées! vous pouvez spécifier un ttl, mais le doc de php.net dit qu'il est effacé à la prochaine demande quand il a expiré ...
The Surrican

Réponses:


145

Vous pouvez utiliser la fonction PHP apc_clear_cache.

L'appel apc_clear_cache()effacera le cache système et l'appel apc_clear_cache('user')effacera le cache utilisateur.


20
J'ai découvert que pour faire cela via la ligne de commande, vous devez aller dans apc.ini et définir: apc.enable_cli = 1
lo_fye

51
lo_fye: Cela fonctionne-t-il réellement? D'après mon expérience, j'ai trouvé qu'APC CLI était totalement distinct du cache APC d'Apache - et à juste titre, puisque tout processus CLI s'exécute dans un processus complètement distinct d'Apache.
Frank Farmer

9
Frank Farmer: Je confirme que cela fonctionne avec Apache ou Nginx exécutant PHP 5.3.10 et l'interface PHP-FPM. J'ai créé un script shell qui exécute cette commandephp -r "apc_clear_cache();"
ezraspectre

13
Cela ne fonctionne PAS si vous exécutez PHP en utilisant mod_php. Pour la raison expliquée par Frank Farmer.
David

11
Je lance Ubuntu Server 12.04 avec Nginx et PHP-FPM avec PHP version 5.4. apc_clear_cache () et apc_clear_cache ('user') sur la ligne de commande ne vident PAS le cache APC du serveur Web / des pages Web !!!
Pieter Vogelaar

117

Je ne crois pas qu'aucune de ces réponses ne fonctionne réellement pour effacer le cache APC de la ligne de commande. Comme Frank Farmer l'a commenté ci-dessus, l'interface de ligne de commande s'exécute dans un processus distinct d'Apache.

Ma solution pour l'effacement de la ligne de commande était d'écrire un script qui copie un script d'effacement APC dans le webrépertoire et y accède, puis le supprime. L'accès au script est limité à partir de l'hôte local.

  1. apc_clear.php

    Il s'agit du fichier que le script copie dans le répertoire Web, accède et supprime.

    <?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. Script d'effacement du cache

    Ce script copie apc_clear.php dans le répertoire Web, y accède, puis le supprime. Ceci est basé sur une tâche Symfony. Dans la version Symfony, les appels sont effectués vers la forme Symfony de copie et de dissociation, qui gère les erreurs. Vous souhaiterez peut-être ajouter des vérifications de leur réussite.

    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']);

8
Vous pouvez également simplement redémarrer le serveur, par exemple Apache si vous utilisez mod_php ou PHP FPM si vous l'utilisez. Votre solution est plus élégante (aucun redémarrage du serveur requis) mais plus complexe :)
El Yobo

5
C'est plus agréable que de redémarrer php-fpm / apache car cela ne nécessite pas que votre utilisateur de déploiement ait un accès sudo. Si vous déployez sur plusieurs serveurs, taper le mot de passe sudo pour chacun peut devenir fastidieux.
andrew

Personnellement, cela ne me dérange pas de taper le mot de passe sudo (mon script de déploiement enregistre le mot de passe). Mais j'aimerais éviter autant que possible les temps d'arrêt, c'est pourquoi je suis intéressé par le vidage des fichiers APC. Pour Nginx, il existe un moyen (pas si simple) de redémarrer sans aucun temps d'arrêt. Je ne sais pas pour PGPfcgi, mais je ne pense pas. Le rinçage APC entraîne-t-il des temps d'arrêt?
Julien

@andrew Vous pouvez configurer votre utilisateur pour qu'il utilise sudo sans saisir votre mot de passe. Cependant, s'il suffit de nettoyer APC, c'est mieux, comme l'a dit Julien.
ChocoDeveloper

1
@Julien Je suppose que cela peut augmenter la charge du serveur si vous stockez des résultats intensifs en CPU ou quelque chose. Je ne le ferais pas à une heure de pointe.
ChocoDeveloper

68

Je sais que ce n'est pas pour tout le monde mais: pourquoi ne pas redémarrer Apache en douceur?

Par exemple dans le cas de Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful

4
Je sais que ce n'est pas idéal, mais je suis heureux que vous ayez mentionné cela pour une solution rapide et sale.
Bryan Petty

1
Désolé d'avoir rouvert ce fil, mais je suis confronté au même problème et je me demande pourquoi un cronjob n'est pas idéal pour un redémarrage apache2 gracieux? Quels sont certains des inconvénients de cette approche?
user2028856

@ user2028856 Il n'y a rien de mal à cela, sauf que certains n'ont pas toujours le contrôle total du serveur. Donc, si cela fonctionne pour vous, utilisez-le.
Tadas Sasnauskas

@TadasSasnauskas Qu'entendez-vous par «ne pas toujours avoir le contrôle total du serveur»? Je veux dire, est-ce que l'exécuter toutes les demi-heures environ provoquera le blocage d'Apache ou interrompra d'autres actions en cours d'exécution telles qu'une sauvegarde cron?
user2028856

@ user2028856 Je voulais dire que certains pourraient héberger leurs sites sur un serveur partagé sans possibilité de redémarrer le serveur Web. Exécuter un redémarrage progressif toutes les 30 minutes devrait être bien, étant donné que vous n'exécutez pas de travail en arrière-plan via cli avec apc activé (pour faire court: dans certains cas, cela peut provoquer une panique du noyau)
Tadas Sasnauskas

29

Ce n'est pas indiqué dans la documentation, mais pour vider le cache de l'opcode, vous devez faire:

apc_clear_cache('opcode');

EDIT: Cela ne semble s'appliquer qu'à certaines anciennes versions d'APC.

Quelle que soit la version que vous utilisez, vous ne pouvez pas effacer le cache APC mod_php ou fastcgi d'un script cli php car le script cli s'exécutera à partir d'un processus différent comme mod_php ou fastcgi. Vous devez appeler apc_clear_cache () depuis le processus (ou processus enfant) pour lequel vous souhaitez vider le cache. Utiliser curl pour exécuter un simple script PHP est une de ces approches.


1
Je dois ajouter que si vous exécutez mod_php et que vous souhaitez vider le cache via php en mode cli, vous ne pouvez pas vraiment le faire car les deux fonctionnent dans des environnements différents. Ma solution était de faire appeler le php en mode cli sur http en utilisant file_get_contents. Moche, mais ça marche.
ColinM

Transférer un dump d'une requête fastcgi valide directement vers php-fpm avec netcat fonctionne sans avoir à installer un vrai serveur http, puisque le serveur php-fpm peut être séparé de celui http
baloo

Cette réponse est fausse. Comme cela est expliqué dans la documentation, le cache de l'opcode est toujours effacé si le paramètre donné est! = 'User'.
naitsirch

@naitsirch C'était peut-être un bogue qui a été corrigé dans la dernière version .. Au moment où j'ai posté la réponse, c'est ce qui fonctionnait pour moi. Malheureusement, je ne sais pas quelle version j'utilisais à l'époque, mais cette réponse est apparemment utile à 25 autres personnes qui utilisaient ostensiblement la même version que moi. La documentation n'est pas toujours correcte et n'est certainement pas toujours correcte pour les anciennes versions.
ColinM du

12

Si vous souhaitez effacer le cache apc dans la commande: (utilisez sudo si vous en avez besoin)

APCu

php -r "apcu_clear_cache();" 

APC

php -r "apc_clear_cache(); apc_clear_cache('user'); apc_clear_cache('opcode');"

J'obtiens une erreur sur mon terminal comme ça s'il vous plaît aidez-moi "Erreur fatale PHP: Appel à la fonction non définie apc_clear_cache () dans le code de ligne de commande sur la ligne 1"
RaviPatidar

1
Vous devriez tester si votre apc est correctement installé avec "php -m | grep apc"
Léo Benoist

9

Si vous utilisez une pile NGINX / PHP-FPM, votre meilleur pari est probablement de simplement recharger php-fpm

service php-fpm reload (ou quelle que soit votre commande de rechargement sur votre système)


service php5-fpm recharger est ce qui le fait fonctionner J'ai vérifié le fichier d'état apc.php et l'état du cache a été réinitialisé J'en avais besoin après avoir ajouté l'option apc.stat = 0 à php.ini
Salem

5

Tel que défini dans le document APC:

Pour vider le cache, exécutez:

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

4

Une autre possibilité d'utilisation de la ligne de commande, non encore mentionnée, est d'utiliser curl.

Cela ne résout pas votre problème pour toutes les entrées de cache si vous utilisez le script stock apc.php, mais cela pourrait appeler un script adapté ou un autre que vous avez mis en place.

Cela efface le cache de l'opcode:

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

Modifiez le paramètre OB sur 3 pour vider le cache utilisateur:

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

Mettez les deux lignes dans un script et appelez-le avec $ PASSWORD dans votre env.


4

Si vous souhaitez surveiller les résultats via json, vous pouvez utiliser ce type de script:

<?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);

Comme mentionné dans d'autres réponses, ce script devra être appelé via http ou curl et vous devrez être sécurisé s'il est exposé dans la racine web de votre application. (par ip, jeton ...)


3

apc_clear_cache () ne fonctionne que sur le même SAPI php que vous souhaitez effacer le cache. Si vous avez PHP-FPM et que vous souhaitez effacer le cache apc, vous devez le faire via l'un des scripts php, PAS la ligne de commande, car les deux caches sont séparés.

J'ai écrit CacheTool , un outil de ligne de commande qui résout exactement ce problème et avec une commande, vous pouvez effacer votre cache PHP-FPM APC à partir de la ligne de commande (il se connecte à php-fpm pour vous et exécute les fonctions apc)

Cela fonctionne également pour opcache.

Voyez comment cela fonctionne ici: http://gordalina.github.io/cachetool/


2

L'écurie d'APC a la possibilité de vider un cache dans son interface elle-même. Pour effacer ces entrées, vous devez vous connecter à l'interface apc.

APC a la possibilité de définir le nom d'utilisateur et le mot de passe dans le fichier apc.php.

entrez la description de l'image ici


Où obtenez-vous cette page?
Pacerier le

@Pacerier Vous obtiendrez cette interface si le php-apcpackage est installé dans votre système.
Stranger

2

si vous exécutez fpm sous ubuntu, vous devez exécuter le code ci-dessous (vérifié sur 12 et 14)

service php5-fpm reload

1

apc.ini

apc.stat = "1" forcera APC à statuer (vérifier) ​​le script à chaque requête pour déterminer s'il a été modifié. S'il a été modifié, il recompilera et mettra en cache la nouvelle version.

Si ce paramètre est désactivé, APC ne vérifiera pas, ce qui signifie généralement que pour forcer APC à revérifier les fichiers, le serveur Web devra être redémarré ou le cache devra être effacé manuellement. Notez que les configurations de serveur Web FastCGI peuvent ne pas vider le cache au redémarrage. Sur un serveur de production où les fichiers de script changent rarement, une amélioration significative des performances peut être obtenue en désactivant les statistiques.


1

La nouvelle interface d'administration APC a des options pour ajouter / effacer le cache utilisateur et le cache opcode, une fonctionnalité intéressante consiste à ajouter / actualiser / supprimer des répertoires à partir du cache opCode

Documentation d'administration APC

entrez la description de l'image ici


0

Une bonne solution pour moi était simplement de ne plus utiliser le cache utilisateur obsolète après le déploiement.

Si vous ajoutez un préfixe à chacune de vos clés, vous pouvez modifier le préfixe en modifiant la structure de données des entrées de cache. Cela vous aidera à obtenir le comportement suivant lors du déploiement:

  1. N'utilisez pas d'entrées de cache obsolètes après le déploiement de structures mises à jour uniquement
  2. Ne nettoyez pas tout le cache lors du déploiement pour ne pas ralentir votre page
  3. Certaines anciennes entrées mises en cache peuvent être réutilisées après avoir annulé votre déploiement (si les entrées n'étaient pas déjà supprimées automatiquement)
  4. APC supprimera les anciennes entrées de cache après expiration OU en cas d'espace de cache manquant

Cela n'est possible que pour le cache utilisateur.


0

Créer un fichier APC.php

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

Exécutez-le depuis votre navigateur.


2
Pour autant que je sache, l'instance CLI ne partagera pas le même segment de mémoire cache APC, donc cela ne fera rien d'autre que d'effacer un segment de cache APC vide et isolé.
AB Carroll

selon les distributions et les configurations, le cache APC peut avoir un segment de mémoire séparé, je l'ai mis à jour pour une solution plus générique.
anshuman

0

Ma solution de contournement pour la version Symfony ayant le pillage des instances sur le même serveur:

Étape 1. Créez un déclencheur ou quelque chose pour définir un indicateur de fichier (par exemple, la commande Symfony), puis créez marker file.

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

Étape 2. Sur le fichier d'index au début, ajoutez le code d'effacement et supprimez-le marker file.

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

Étape 2. Exécutez l'application.


-1

Nous avons eu un problème avec APC et des liens symboliques vers des liens symboliques vers des fichiers - il semble ignorer les changements dans les fichiers eux-mêmes. En quelque sorte, effectuer un toucher sur le fichier lui-même a aidé. Je ne peux pas dire quelle est la différence entre modifier un fichier et le toucher, mais en quelque sorte c'était nécessaire ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.