Jak wyczyścić wpisy pamięci podręcznej APC?


170

Muszę wyczyścić wszystkie wpisy pamięci podręcznej APC, kiedy wdrażam nową wersję witryny. APC.php ma przycisk do czyszczenia wszystkich pamięci podręcznych kodu operacji, ale nie widzę przycisków do usuwania wszystkich wpisów użytkowników, wszystkich wpisów systemowych lub wszystkich wpisów w katalogu.

Czy można wyczyścić wszystkie wpisy pamięci podręcznej za pomocą wiersza poleceń lub w inny sposób?


1
byłbym zainteresowany, jak wyczyścić wygasłe wpisy! możesz określić ttl, ale dokument php.net mówi, że jest on usuwany przy następnym żądaniu, gdy wygasa ...
The Surrican

Odpowiedzi:


145

Możesz użyć funkcji PHP apc_clear_cache.

Wywołanie apc_clear_cache()wyczyści pamięć podręczną systemu, a wywołanie apc_clear_cache('user')wyczyści pamięć podręczną użytkownika.


20
Odkryłem, że aby to zrobić za pomocą wiersza poleceń, musisz wejść do apc.ini i ustawić: apc.enable_cli = 1
lo_fye

51
lo_fye: Czy to faktycznie działa? Z mojego doświadczenia wynika, że ​​APC CLI był całkowicie niezależny od pamięci podręcznej APC Apache - i słusznie, ponieważ każdy proces CLI działa w całkowicie oddzielnym procesie od Apache.
Frank Farmer

9
Frank Farmer: Potwierdzam, że to działa z Apache lub Nginx z PHP 5.3.10 i interfejsem PHP-FPM. Stworzyłem skrypt powłoki, który wykonuje to poleceniephp -r "apc_clear_cache();"
ezraspectre

13
To NIE działa, jeśli uruchamiasz PHP za pomocą mod_php. Z tego powodu Frank Farmer stwierdził.
David

11
Używam Ubuntu Server 12.04 z Nginx i PHP-FPM z PHP w wersji 5.4. apc_clear_cache () i apc_clear_cache ('user') w wierszu poleceń NIE czyść pamięci podręcznej APC serwera / stron internetowych !!!
Pieter Vogelaar

117

Nie sądzę, aby którakolwiek z tych odpowiedzi faktycznie działała przy czyszczeniu pamięci podręcznej APC z wiersza poleceń. Jak skomentował Frank Farmer powyżej, CLI działa w procesie niezależnym od Apache.

Moim rozwiązaniem do czyszczenia z wiersza poleceń było napisanie skryptu, który kopiuje skrypt rozliczeniowy APC do webkatalogu i uzyskuje do niego dostęp, a następnie usuwa go. Skrypt jest ograniczony do dostępu z lokalnego hosta.

  1. apc_clear.php

    Jest to plik, który skrypt kopiuje do katalogu WWW, uzyskuje do niego dostęp i usuwa.

    <?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. Skrypt do czyszczenia pamięci podręcznej

    Ten skrypt kopiuje plik apc_clear.php do katalogu WWW, uzyskuje do niego dostęp, a następnie usuwa go. Jest to oparte na zadaniu Symfony. W wersji Symfony wywołania są wywoływane w postaci Symfony kopiuj i odłącz, która obsługuje błędy. Możesz chcieć dodać testy, które się powiodły.

    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
Możesz także po prostu zrestartować serwer, np. Apache, jeśli używasz mod_php lub PHP FPM, jeśli używasz tego. Twoje rozwiązanie jest bardziej eleganckie (nie wymaga restartu serwera), ale bardziej złożone :)
El Yobo,

5
Jest to przyjemniejsze niż ponowne uruchomienie php-fpm / apache, ponieważ nie wymaga, aby użytkownik wdrażania miał dostęp do sudo. Jeśli wdrażasz na wielu serwerach, wpisywanie hasła sudo dla każdego może być męczące.
andrew

Osobiście nie mam nic przeciwko wpisaniu hasła sudo (mój skrypt wdrożeniowy zapisuje hasło). Ale chciałbym jak najbardziej uniknąć przestojów, dlatego jestem zainteresowany opróżnianiem plików APC. W przypadku Nginx istnieje (nie tak łatwy) sposób na ponowne uruchomienie bez przestojów. Nie wiem o PGPfcgi, ale nie sądzę. Czy płukanie APC powoduje przestoje?
Julien,

@andrew Możesz skonfigurować użytkownika, aby używał sudo bez wpisywania hasła. Chociaż wystarczy wyczyścić APC, to rzeczywiście lepiej, jak powiedział Julien.
ChocoDeveloper

1
@Julien Wydaje mi się, że może to zwiększyć obciążenie serwera, jeśli przechowujesz wyniki intensywne dla procesora lub coś takiego. Nie robiłbym tego w godzinach szczytu.
ChocoDeveloper

68

Wiem, że to nie jest dla wszystkich, ale: dlaczego nie zrobić wdzięcznego restartu Apache?

Na przykład w przypadku Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful

4
Wiem, że to nie jest idealne rozwiązanie, ale cieszę się, że wspomniałeś o tym, aby uzyskać szybkie i brudne rozwiązanie.
Bryan Petty

1
Przepraszam za ponowne otwarcie tego wątku, ale mam ten sam problem i zastanawiam się, dlaczego cronjob nie sprawia, że ​​wdzięczny restart apache2 nie jest idealny? Jakie są wady tego podejścia?
user2028856

@ user2028856 Nie ma w tym nic złego, poza tym, że niektórzy nie zawsze mają pełną kontrolę nad serwerem. Więc jeśli to działa dla Ciebie - użyj go.
Tadas Sasnauskas,

@TadasSasnauskas Co masz na myśli mówiąc „nie zawsze masz pełną kontrolę nad serwerem”? Chodzi mi o to, czy uruchamianie go co pół godziny spowoduje awarię Apache lub przerwanie innych uruchomionych działań, takich jak kopia zapasowa cron?
user2028856

@ user2028856 Chodziło mi o to, że niektórzy mogą hostować swoje witryny na współdzielonym serwerze bez możliwości ponownego uruchomienia serwera WWW. Uruchamianie wdzięku restartu każdy 30min powinno być w porządku biorąc pod uwagę, że nie działają w tle pracowników poprzez CLI z APC włączone (krótko mówiąc: w niektórych przypadkach może powodować kernel panic)
Tadas Sasnauskas

29

Nie jest to określone w dokumentacji, ale aby wyczyścić pamięć podręczną kodu operacyjnego, musisz:

apc_clear_cache('opcode');

EDYCJA: Wydaje się, że dotyczy to tylko niektórych starszych wersji APC.

Bez względu na to, jakiej wersji używasz, nie możesz wyczyścić pamięci podręcznej APC mod_php lub fastcgi ze skryptu php cli, ponieważ skrypt cli będzie uruchamiany z innego procesu, jak mod_php lub fastcgi. Musisz wywołać apc_clear_cache () z poziomu procesu (lub procesu potomnego), dla którego chcesz wyczyścić pamięć podręczną. Jednym z takich podejść jest użycie curl do uruchomienia prostego skryptu php.


1
Powinienem dodać, że jeśli używasz mod_php i chcesz wyczyścić pamięć podręczną przez php w trybie cli, nie możesz tego zrobić, ponieważ oba działają w różnych środowiskach. Moim rozwiązaniem było wywołanie php w trybie cli przez http przy użyciu file_get_contents. Brzydkie, ale działa.
ColinM

Przesyłanie zrzutu poprawnego żądania fastcgi bezpośrednio do php-fpm za pomocą netcata działa bez konieczności instalowania prawdziwego serwera http, ponieważ serwer php-fpm może być oddzielony od serwera http
baloo

Ta odpowiedź jest błędna. Jak wyjaśniono w dokumentacji, pamięć podręczna kodu operacji jest zawsze czyszczona, jeśli podanym parametrem jest! = 'User'.
naitsirch

@naitsirch Być może był to błąd, który został naprawiony w najnowszej wersji .. W czasie, gdy opublikowałem odpowiedź, to właśnie działało dla mnie. Niestety nie wiem, jakiej wersji wtedy używałem, ale ta odpowiedź jest najwyraźniej przydatna dla 25 innych osób, które rzekomo korzystały z tej samej wersji co ja. Dokumentacja nie zawsze jest poprawna i zdecydowanie nie zawsze jest poprawna dla starszych wersji.
ColinM,

12

Jeśli chcesz wyczyścić pamięć podręczną apc w poleceniu: (użyj sudo, jeśli tego potrzebujesz)

APCu

php -r "apcu_clear_cache();" 

APC

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

Na moim terminalu pojawia się taki błąd, proszę mi pomóc "Błąd krytyczny PHP: wywołanie niezdefiniowanej funkcji apc_clear_cache () w kodzie wiersza poleceń w linii 1"
RaviPatidar

1
Powinieneś sprawdzić, czy twój apc jest poprawnie zainstalowany za pomocą "php -m | grep apc"
Léo Benoist

9

Jeśli korzystasz ze stosu NGINX / PHP-FPM, najlepiej jest po prostu przeładować php-fpm

service php-fpm reload (lub jakakolwiek twoja komenda przeładowania może być w twoim systemie)


usługa przeładowanie php5-fpm sprawia, że ​​działa Sprawdziłem plik stanu apc.php i stan pamięci podręcznej został zresetowany Potrzebowałem tego po dodaniu opcji apc.stat = 0 do php.ini
Salem

5

Zgodnie z definicją w dokumencie APC:

Aby wyczyścić pamięć podręczną, wykonaj:

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

4

Inną możliwością użycia wiersza poleceń, jeszcze nie wspomnianą, jest użycie curl.

Nie rozwiązuje to problemu dla wszystkich wpisów w pamięci podręcznej, jeśli używasz standardowego skryptu apc.php, ale może wywołać dostosowany skrypt lub inny, który umieściłeś.

Spowoduje to wyczyszczenie pamięci podręcznej kodu operacji:

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

Zmień parametr OB na 3, aby wyczyścić pamięć podręczną użytkownika:

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

Umieść obie linie w skrypcie i wywołaj go z $ PASSWORD w swoim pliku env.


4

Jeśli chcesz monitorować wyniki za pomocą json, możesz użyć tego rodzaju skryptu:

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

Jak wspomniano w innych odpowiedziach, ten skrypt będzie musiał być wywoływany przez http lub curl i będziesz musiał być zabezpieczony, jeśli zostanie ujawniony w katalogu głównym aplikacji. (przez ip, token ...)


3

apc_clear_cache () działa tylko na tym samym php SAPI, na którym chcesz wyczyścić pamięć podręczną. Jeśli masz PHP-FPM i chcesz wyczyścić pamięć podręczną apc, musisz to zrobić za pomocą jednego ze skryptów php, a NIE wiersza poleceń, ponieważ dwie pamięci podręczne są oddzielone.

Napisałem CacheTool , narzędzie wiersza poleceń, które rozwiązuje dokładnie ten problem i jednym poleceniem możesz wyczyścić pamięć podręczną APC PHP-FPM z wiersza poleceń (łączy się z php-fpm i wykonuje funkcje apc)

Działa również w przypadku opcache.

Zobacz, jak to działa tutaj: http://gordalina.github.io/cachetool/


2

Stajnia APC ma możliwość wyczyszczenia pamięci podręcznej w samym interfejsie. Aby wyczyścić te wpisy, musisz zalogować się do interfejsu apc.

APC ma opcję ustawienia nazwy użytkownika i hasła w pliku apc.php.

wprowadź opis obrazu tutaj


Skąd masz tę stronę?
Pacerier

@Pacerier Otrzymasz ten interfejs, jeśli masz php-apczainstalowany pakiet w swoim systemie.
Stranger

2

jeśli uruchamiasz fpm pod ubuntu, musisz uruchomić poniższy kod (zaznaczone na 12 i 14)

service php5-fpm reload

1

apc.ini

apc.stat = "1" zmusi firmę APC do stat (sprawdzenia) skryptu przy każdym żądaniu w celu określenia, czy został on zmodyfikowany. Jeśli został zmodyfikowany, skompiluje ponownie i buforuje nową wersję.

Jeśli to ustawienie jest wyłączone, firma APC nie sprawdzi, co zwykle oznacza, że ​​aby wymusić ponowne sprawdzenie plików przez firmę APC, konieczne będzie ponowne uruchomienie serwera WWW lub ręczne wyczyszczenie pamięci podręcznej. Należy pamiętać, że konfiguracje serwera WWW FastCGI mogą nie wyczyścić pamięci podręcznej po ponownym uruchomieniu. Na serwerze produkcyjnym, na którym pliki skryptów rzadko się zmieniają, wyłączone statystyki mogą znacznie zwiększyć wydajność.


1

Nowy interfejs administratora APC ma opcje dodawania / czyszczenia pamięci podręcznej użytkownika i pamięci podręcznej kodu operacji.Jedną interesującą funkcją jest dodawanie / odświeżanie / usuwanie katalogów z pamięci podręcznej opCode

Dokumentacja administratora APC

wprowadź opis obrazu tutaj


0

Dobrym rozwiązaniem dla mnie było po prostu zaprzestanie używania przestarzałej pamięci podręcznej użytkowników po wdrożeniu.

Jeśli dodasz prefiks do każdego z kluczy, możesz zmienić przedrostek przy zmianie struktury danych wpisów pamięci podręcznej. Pomoże ci to uzyskać następujące zachowanie podczas wdrażania:

  1. Nie używaj przestarzałych wpisów pamięci podręcznej po wdrożeniu tylko zaktualizowanych struktur
  2. Nie czyść całej pamięci podręcznej podczas wdrażania, aby nie spowalniać strony
  3. Niektóre stare wpisy z pamięci podręcznej można ponownie wykorzystać po przywróceniu wdrożenia (jeśli wpisy nie zostały już automatycznie usunięte)
  4. APC usunie stare wpisy z pamięci podręcznej po wygaśnięciu LUB w przypadku braku miejsca w pamięci podręcznej

Jest to możliwe tylko w przypadku pamięci podręcznej użytkownika.


0

Utwórz plik APC.php

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

Uruchom go z przeglądarki.


2
O ile rozumiem, instancja CLI nie będzie współużytkować tego samego segmentu pamięci podręcznej APC, więc spowoduje to jedynie wyczyszczenie pustego, izolowanego segmentu pamięci podręcznej APC.
AB Carroll,

w zależności od dystrybucji i konfiguracji Pamięć podręczna APC może mieć oddzielny segment pamięci. Zaktualizowałem ją w celu uzyskania bardziej ogólnego rozwiązania.
anshuman

0

Moje obejście dla kompilacji Symfony mającej łupy z instancji na tym samym serwerze:

Krok 1. Utwórz wyzwalacz lub coś w celu ustawienia flagi pliku (np. Polecenie Symfony), a następnie utwórz marker file..

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

Krok 2. W pliku indeksu na początku dodaj kod rozliczeniowy i usuń marker file.

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

Krok 2. Uruchom aplikację.


-1

Mieliśmy problem z APC i dowiązaniami symbolicznymi do dowiązań symbolicznych do plików - wydaje się, że ignoruje zmiany w samych plikach. W jakiś sposób pomogło dotknięcie samego pliku. Nie potrafię powiedzieć, jaka jest różnica między modyfikacją pliku a dotknięciem go, ale jakoś było to konieczne ...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.