Como limpar as entradas de cache da APC?

170

Preciso limpar todas as entradas de cache da APC ao implantar uma nova versão do site. O APC.php possui um botão para limpar todos os caches de código de operação, mas não vejo botões para limpar todas as entradas do usuário, todas as entradas do sistema ou todas as entradas por diretório.

É possível limpar todas as entradas de cache por meio da linha de comando ou de alguma outra maneira?

lo_fye
fonte
1
eu estaria interessado em como limpar entradas expiradas! você pode especificar um TTL, mas php.net doc diz que está expurgado após a próxima solicitação quando expirou ...
O Surrican

Respostas:

145

Você pode usar a função PHP apc_clear_cache.

A chamada apc_clear_cache()limpará o cache do sistema e a chamada apc_clear_cache('user')limpará o cache do usuário.

Travis Beale
fonte
20
Descobri que para fazer isso através de linha de comando que você precisa para entrar em apc.ini e set: apc.enable_cli = 1
lo_fye
51
lo_fye: Isso realmente funciona? Na minha experiência, descobri que a CLI da APC era totalmente separada do cache da APC do apache - e com razão, pois qualquer processo da CLI é executado em um processo completamente separado do Apache.
Frank Farmer
9
Frank Farmer: Confirmo que isso funciona com o Apache ou o Nginx executando o PHP 5.3.10 e a interface PHP-FPM. Eu criei um script shell que executa este comandophp -r "apc_clear_cache();"
ezraspectre
13
Isso NÃO funciona se você executar o PHP usando o mod_php. Pela razão que Frank Farmer declarou.
David
11
Executo o Ubuntu Server 12.04 com Nginx e PHP-FPM com PHP versão 5.4. apc_clear_cache () e apc_clear_cache ('usuário') na linha de comando NÃO limpe o cache da APC do servidor da web / páginas da web !!!
Pieter Vogelaar
117

Não acredito que nenhuma dessas respostas realmente funcione para limpar o cache da APC da linha de comando. Como Frank Farmer comentou acima, a CLI é executada em um processo separado do Apache.

Minha solução para limpar a partir da linha de comando foi escrever um script que copie um script de limpeza da APC para o webdiretório, acesse-o e exclua-o. O script está restrito a ser acessado a partir do host local.

  1. apc_clear.php

    Este é o arquivo que o script copia para o diretório da web, acessa e exclui.

    <?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 de limpeza de cache

    Este script copia apc_clear.php para o diretório da web, acessa-o e exclui-o. Isso é baseado em uma tarefa do Symfony. Na versão Symfony, as chamadas são feitas para a forma Symfony de copiar e desvincular, que lida com erros. Você pode querer adicionar verificações para que tenham sucesso.

    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
fonte
8
Você também pode simplesmente reiniciar o servidor, por exemplo, Apache se você estiver usando mod_php ou PHP FPM, se estiver usando isso. Sua solução é mais elegante (sem reinicialização do servidor necessário), mas mais complexo :)
El Yobo
5
É melhor do que reiniciar o php-fpm / apache porque não exige que o usuário de implantação tenha acesso ao sudo. Se você estiver implantando em vários servidores, digitar a senha do sudo para cada um pode ser cansativo.
andrew
Pessoalmente, não me importo de digitar a senha do sudo (meu script de implantação salva a senha). Mas gostaria de evitar o máximo de tempo de inatividade, por isso estou interessado em liberar arquivos da APC. Para o Nginx, existe uma maneira (não tão fácil) de reiniciar sem nenhum tempo de inatividade. Não conheço o PGPfcgi, mas acho que não. A descarga da APC causa tempo de inatividade?
214 Julien
@andrew Você pode configurar seu usuário para usar o sudo sem digitar sua senha. Embora se for necessário limpar a APC, isso é realmente melhor, como Julien disse.
ChocoDeveloper
1
@ Julien Eu acho que pode aumentar a carga do servidor se você estiver armazenando resultados intensivos da CPU ou algo assim. Eu não faria isso no horário de pico.
ChocoDeveloper 04/04
68

Eu sei que não é para todos, mas: por que não fazer um reinício gracioso do Apache?

Por exemplo, no caso do Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful
Tadas Sasnauskas
fonte
4
Sei que isso não é o ideal, mas fico feliz que você tenha mencionado isso para uma solução rápida e suja.
Bryan Petty
1
Desculpe por reabrir este tópico, mas estou enfrentando o mesmo problema e estou me perguntando por que um cronjob não está tornando ideal uma reinicialização apache2 graciosa? Quais são algumas das desvantagens dessa abordagem?
precisa saber é o seguinte
@ user2028856 Não há nada de errado com isso, exceto alguns nem sempre podem ter controle total do servidor. Portanto, se funcionar para você - use-o.
Tadas Sasnauskas
@TadasSasnauskas O que você quer dizer com "nem sempre tem controle total do servidor"? Quero dizer, executá-lo a cada meia hora ou mais faz com que o apache falhe ou quebre outras ações em execução, como um backup cron.
precisa saber é o seguinte
@ user2028856 quis dizer que alguns podem hospedar seus sites em um servidor compartilhado sem capacidade de reiniciar o servidor da web. Correndo graciosa reiniciar a cada 30min deve ser excelentes dado que você não corra trabalhadores de fundo via cli com apc ativado (longa história curta: em alguns casos, pode causar kernel do pânico)
Tadas Sasnauskas
29

Isso não está indicado na documentação, mas para limpar o cache do opcode, você deve fazer:

apc_clear_cache('opcode');

EDIT: Isso parece se aplicar apenas a algumas versões mais antigas do APC.

Não importa qual versão você está usando, você não pode limpar o cache da APC mod_php ou fastcgi de um script php cli, pois o script cli será executado a partir de um processo diferente como mod_php ou fastcgi. Você deve chamar apc_clear_cache () de dentro do processo (ou processo filho) para o qual deseja limpar o cache. Usar curl para executar um script php simples é uma dessas abordagens.

ColinM
fonte
1
Devo acrescentar que, se você estiver executando o mod_php e quiser limpar o cache via php no modo CLI, não será possível fazer isso, pois os dois estão sendo executados em ambientes diferentes. Minha solução foi fazer com que o php do modo cli se chamasse por http usando file_get_contents. Feio, mas funciona.
ColinM
Pipe'ing um despejo de um pedido fastcgi válida diretamente para php-fpm com obras netcat sem ter que instalar um servidor http real, já que o servidor php-fpm pode ser separado do http um
baloo
Esta resposta está errada. Como é explicado na documentação, o cache do opcode é sempre limpo se o parâmetro fornecido for! = 'User'.
naitsirch
@naitsirch Talvez este tenha sido um bug corrigido na versão mais recente. No momento em que publiquei a resposta, foi isso que funcionou para mim. Infelizmente, não sei qual versão eu estava usando no momento, mas esta resposta é aparentemente útil para outras 25 pessoas que usavam ostensivamente a mesma versão que eu estava. A documentação nem sempre está correta e definitivamente nem sempre está correta para versões mais antigas.
ColinM
12

Se você deseja limpar o cache do apc no comando: (use sudo, se necessário)

APCu

php -r "apcu_clear_cache();" 

APC

php -r "apc_clear_cache(); apc_clear_cache('user'); apc_clear_cache('opcode');"
Léo Benoist
fonte
Estou recebendo erro no meu terminal como o que ajuda por favor me "PHP Erro fatal: Chamada para apc_clear_cache função indefinida () no código de linha de comando na linha 1"
RaviPatidar
1
Você deve testar se o seu apc está instalado corretamente com "php -m | grep apc"
Léo Benoist
9

Se você estiver executando em uma pilha NGINX / PHP-FPM, sua melhor aposta é provavelmente apenas recarregar o php-fpm

service php-fpm reload (ou qualquer que seja o seu comando de recarga no seu sistema)

passion4code
fonte
serviço php5-fpm reload é o que o faz funcionar Verifiquei o arquivo de status apc.php e o status do cache foi redefinido Eu era necessário após adicionar a opção apc.stat = 0 ao php.ini
Salem
5

Conforme definido no documento da APC:

Para limpar o cache, execute:

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

Outra possibilidade para o uso da linha de comando, ainda não mencionada, é usar curl.

Isso não resolve o problema de todas as entradas de cache se você estiver usando o script stock apc.php, mas poderia chamar um script adaptado ou outro que você colocou no lugar.

Isso limpa o cache do opcode:

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

Altere o parâmetro OB para 3 para limpar o cache do usuário:

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

Coloque as duas linhas em um script e chame-o com $ PASSWORD em seu ambiente.

Andy Triggs
fonte
4

Se você deseja monitorar os resultados via json, pode usar este tipo 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);

Conforme mencionado em outras respostas, esse script precisará ser chamado via http ou curl e você precisará ser protegido se for exposto na raiz da web do seu aplicativo. (por ip, token ...)

Bobina
fonte
3

apc_clear_cache () funciona apenas no mesmo php SAPI que você deseja que o cache seja limpo. Se você possui PHP-FPM e deseja limpar o cache do apc, faça-o através de um dos scripts php, NÃO da linha de comando, porque os dois caches são separados.

Eu escrevi CacheTool , uma ferramenta de linha de comando que resolve exatamente esse problema e com um comando você pode limpar o cache do PHP-FPM APC na linha de comando (ele se conecta ao php-fpm para você e executa as funções do apc)

Também funciona para o opcache.

Veja como funciona aqui: http://gordalina.github.io/cachetool/

Samuel Gordalina
fonte
2

O estábulo da APC está tendo a opção de limpar um cache em sua própria interface. Para limpar essas entradas, você deve fazer login na interface do apc.

A APC está tendo a opção de definir nome de usuário e senha no arquivo apc.php.

insira a descrição da imagem aqui

vinothvetrivel
fonte
De onde você tira essa página?
Pacerier 02/09/2015
@Pacerier Você obterá essa interface se tiver um php-apcpacote instalado no seu sistema.
Stranger
2

se você executar o fpm no ubuntu, precisará executar o código abaixo (verificado em 12 e 14)

service php5-fpm reload
hrnsky
fonte
1

apc.ini

apc.stat = "1" forçará a APC a stat (verificar) o script em cada solicitação para determinar se ele foi modificado. Se foi modificado, ele irá recompilar e armazenar em cache a nova versão.

Se essa configuração estiver desativada, a APC não irá verificar, o que geralmente significa que, para forçar a APC a verificar novamente os arquivos, o servidor da Web precisará ser reiniciado ou o cache deverá ser limpo manualmente. Observe que as configurações do servidor da Web FastCGI podem não limpar o cache na reinicialização. Em um servidor de produção em que os arquivos de script raramente mudam, um aumento significativo no desempenho pode ser alcançado pelas estatísticas desabilitadas.

mal
fonte
1

A nova interface de administração da APC tem opções para adicionar / limpar o cache do usuário e o código do opcode. Uma funcionalidade interessante é adicionar / atualizar / excluir os diretórios do cache do opCode

Documentação de administrador da APC

insira a descrição da imagem aqui

Jithin Jose
fonte
0

Uma boa solução para mim foi simplesmente não usar mais o cache desatualizado do usuário após a implantação.

Se você adicionar prefixo a cada uma das chaves, poderá alterar o prefixo ao alterar a estrutura de dados das entradas de cache. Isso ajudará você a obter o seguinte comportamento na implantação:

  1. Não use entradas de cache desatualizadas após implantar apenas estruturas atualizadas
  2. Não limpe todo o cache ao implantar para não diminuir a velocidade da sua página
  3. Algumas entradas em cache antigas podem ser reutilizadas após a reversão da sua implantação (se as entradas já não tiverem sido removidas automaticamente)
  4. A APC removerá as entradas antigas do cache após expirar OU no espaço em cache ausente

Isso é possível apenas para o cache do usuário.

mabe.berlin
fonte
0

Criar arquivo APC.php

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

Execute-o no seu navegador.

anshuman
fonte
2
Pelo que entendi, a instância da CLI não compartilhará o mesmo segmento de memória de cache da APC, portanto, isso não fará nada além de limpar um segmento de cache da APC vazio e isolado.
AB Carroll
dependendo das distribuições e configurações, o cache da APC pode ter um segmento de memória separado, sendo atualizado para uma solução mais genérica.
Anshuman 27/03
0

Minha solução alternativa para a construção do Symfony com várias instâncias no mesmo servidor:

Etapa 1. Crie um gatilho ou algo para definir um sinalizador de arquivo (por exemplo, comando Symfony) e depois crie marker file..

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

Etapa 2. No arquivo de índice no início, adicione o código de limpeza e remova marker file.

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

Etapa 2. Execute o aplicativo.

Ajsti.pl - Maciej Szewczyk
fonte
-1

Tivemos um problema com a APC e os links simbólicos para links simbólicos para arquivos - parece ignorar as alterações nos próprios arquivos. De alguma forma, executar o toque no arquivo em si ajudou. Não sei dizer qual é a diferença entre modificar um arquivo e tocá-lo, mas de alguma forma era necessário ...

jakub.lopuszanski
fonte