Как очистить записи в кэше APC?


170

Мне нужно очистить все записи кэша APC при развертывании новой версии сайта. APC.php имеет кнопку для очистки всех кэшей кода операции, но я не вижу кнопок для очистки всех записей пользователя, или всех системных записей, или всех записей для каждого каталога.

Можно ли очистить все записи кэша через командную строку или каким-либо другим способом?


1
Мне было бы интересно, как очистить просроченные записи! Вы можете указать ttl, но документ php.net говорит, что он удаляется при следующем запросе, когда он истек ...
Surrican

Ответы:


145

Вы можете использовать функцию PHP apc_clear_cache.

Вызов apc_clear_cache()очистит системный кеш, а вызов apc_clear_cache('user')очистит пользовательский кеш.


20
Я обнаружил, что для этого через командную строку вам нужно зайти в apc.ini и установить: apc.enable_cli = 1
lo_fye

51
lo_fye: Это на самом деле работает? Исходя из своего опыта, я обнаружил, что CLI APC полностью отделен от кэша APC apache - и это справедливо, поскольку любой процесс CLI выполняется в совершенно отдельном процессе от Apache.
Фрэнк Фармер

9
Фрэнк Фармер: Я подтверждаю, что это работает с Apache или Nginx с PHP 5.3.10 и интерфейсом PHP-FPM. Я создал сценарий оболочки, который выполняет эту командуphp -r "apc_clear_cache();"
ezraspectre

13
Это НЕ работает, если вы запускаете PHP с помощью mod_php. По этой причине Фрэнк Фармер заявил.
Дэвид

11
Я запускаю Ubuntu Server 12.04 с Nginx и PHP-FPM с PHP версии 5.4. apc_clear_cache () и apc_clear_cache ('user') в командной строке НЕ очищают кэш APC веб-сервера / веб-страниц !!!
Питер Фогелаар

117

Я не верю, что какой-либо из этих ответов действительно работает для очистки кэша APC из командной строки. Как заметил Фрэнк Фармер выше, CLI работает в процессе, отдельном от Apache.

Моим решением для очистки из командной строки было написать сценарий, который копирует сценарий очистки APC в webкаталог, получает к нему доступ и затем удаляет его. Доступ к сценарию ограничен локальным хостом.

  1. apc_clear.php

    Это файл, который сценарий копирует в веб-каталог, получает к нему доступ и удаляет его.

    <?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. Скрипт очистки кеша

    Этот скрипт копирует apc_clear.php в веб-каталог, получает к нему доступ, затем удаляет его. Это основано на задаче Symfony. В версии Symfony обращаются к форме копирования и отмены связи Symfony, которая обрабатывает ошибки. Вы можете добавить проверки, что они успешны.

    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
Вы также можете просто перезапустить сервер, например, Apache, если вы используете mod_php или PHP FPM, если вы его используете. Ваше решение более элегантное (перезапуск сервера не требуется), но более сложное :)
El Yobo

5
Это лучше, чем перезапуск php-fpm / apache, потому что не требует, чтобы у вашего пользователя развертывания был доступ sudo. Если вы развертываете на нескольких серверах, ввод пароля sudo для каждого из них может быть утомительным.
Андрей

Лично я не против набрать пароль sudo (мой сценарий развертывания сохраняет пароль). Но я бы хотел как можно больше избегать простоев, поэтому я заинтересован в удалении файлов APC. Для Nginx есть (не очень простой) способ перезагрузки без простоев. Я не знаю для PGPfcgi, но я так не думаю. Вызывает ли промывка APC время простоя?
Жюльен

@andrew Вы можете настроить своего пользователя на использование sudo без ввода пароля. Хотя, если очистка APC - это все, что нужно, это действительно лучше, как сказал Жюльен.
ChocoDeveloper

1
@Julien Я думаю, это может увеличить нагрузку на сервер, если вы сохраняете результаты процессора или что-то в этом роде. Я бы не стал делать это в час пик.
ChocoDeveloper

68

Я знаю, что это не для всех, но: почему бы не сделать изящный перезапуск Apache?

Например, в случае с Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful

4
Я знаю, что это не идеально, но я рад, что вы упомянули это для быстрого и грязного решения.
Брайан Петти

1
Извините за повторное открытие этой темы, но я столкнулся с той же проблемой, и мне интересно, почему cronjob не делает изящный перезапуск apache2 идеальным? Каковы некоторые недостатки этого подхода?
user2028856

@ user2028856 В этом нет ничего плохого, за исключением того, что некоторые не всегда могут полностью контролировать сервер. Так что, если это работает для вас - используйте это.
Тадас Саснаускас

@TadasSasnauskas Что вы подразумеваете под «не всегда иметь полный контроль над сервером»? Я имею в виду, будет ли запускать его каждые полчаса или около того, чтобы Apache аварийно завершал работу или нарушал некоторые другие выполняющиеся действия, такие как cron backup?
user2028856

@ user2028856 Я имел в виду, что некоторые могут разместить свои сайты на общем сервере без возможности перезапустить веб-сервер. Выполнять изящный перезапуск каждые 30 минут должно быть хорошо, если вы не запускаете фоновых рабочих с помощью cli с включенным apc (короче говоря: в некоторых случаях это может вызвать панику ядра)
Tadas Sasnauskas

29

Это не указано в документации, но для очистки кэша кода операции вы должны сделать:

apc_clear_cache('opcode');

РЕДАКТИРОВАТЬ: Это, кажется, относится только к некоторым старым версиям APC.

Независимо от того, какую версию вы используете, вы не можете очистить кэш mod_php или fastcgi APC из скрипта php cli, так как скрипт cli будет запускаться из другого процесса, такого как mod_php или fastcgi. Вы должны вызвать apc_clear_cache () внутри процесса (или дочернего процесса), для которого вы хотите очистить кеш. Использование curl для запуска простого php-скрипта - один из таких подходов.


1
Я должен добавить, что если вы работаете с mod_php и хотите очистить кеш через cli-mode php, вы не сможете этого сделать, так как они работают в разных средах. Мое решение состояло в том, чтобы php-режим cli вызывался через http с помощью file_get_contents. Уродливо, но это работает.
ColinM

Передача дампа действительного запроса fastcgi непосредственно в php-fpm с помощью netcat работает без необходимости установки реального http-сервера, поскольку сервер php-fpm может быть отделен от http-сервера
baloo

Этот ответ неверен. Как объяснено в документации, кэш кода операции всегда очищается, если задан параметр! = 'User'.
naitsirch

@naitsirch Возможно, это была ошибка, которая исправлена ​​в последней версии. В то время, когда я публиковал ответ, это то, что работало для меня. К сожалению, я не знаю, какую версию я использовал в то время, но этот ответ, по-видимому, полезен для 25 других людей, которые якобы использовали ту же версию, что и я. Документация не всегда верна и определенно не всегда верна для более старых версий.
ColinM

12

Если вы хотите очистить кэш apc в команде: (используйте sudo, если вам это нужно)

APCu

php -r "apcu_clear_cache();" 

APC

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

Я получаю ошибку на своем терминале, как это, пожалуйста, помогите мне "PHP Fatal error: вызов неопределенной функции apc_clear_cache () в коде командной строки в строке 1"
RaviPatidar

1
Вы должны проверить, правильно ли установлен ваш apc с помощью "php -m | grep apc"
Léo Benoist

9

Если вы работаете в стеке NGINX / PHP-FPM, лучше всего просто перезагрузить php-fpm

service php-fpm reload (или какая-либо ваша команда перезагрузки может быть в вашей системе)


Сервис php5-fpm reload - вот что заставляет его работать. Я проверил файл состояния apc.php и статус кэша был сброшен. Мне это понадобилось после добавления опции apc.stat = 0 в php.ini
Салем

5

Как определено в документе APC:

Для очистки кеша выполните:

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

4

Еще одна возможность использования командной строки, еще не упомянутая, это использование curl.

Это не решит вашу проблему для всех записей кэша, если вы используете стандартный скрипт apc.php, но он может вызвать адаптированный сценарий или другой, который вы установили.

Это очищает кэш кода операции:

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

Измените параметр OB на 3, чтобы очистить кэш пользователя:

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

Поместите обе строки в скрипт и назовите его с $ PASSWORD в вашем env.


4

Если вы хотите отслеживать результаты через json, вы можете использовать этот вид сценария:

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

Как упоминалось в других ответах, этот сценарий нужно будет вызывать через http или curl, и вы должны быть защищены, если он отображается в корневом каталоге вашего приложения. (по ip, токен ...)


3

apc_clear_cache () работает только на том же php SAPI, который вы хотите очистить кеш. Если у вас есть PHP-FPM и вы хотите очистить кэш apc, вы должны сделать это с помощью одного из сценариев php, а НЕ командной строки, потому что два кэша разделены.

Я написал CacheTool , инструмент командной строки, который решает именно эту проблему, и с помощью одной команды вы можете очистить кэш PHP-FPM APC из командной строки (он подключается к php-fpm для вас и выполняет функции apc)

Это также работает для opcache.

Посмотрите, как это работает здесь: http://gordalina.github.io/cachetool/


2

Конюшня APC имеет возможность очищать кеш в своем интерфейсе. Чтобы очистить эти записи, вы должны войти в интерфейс apc.

APC имеет возможность установить имя пользователя и пароль в файле apc.php.

введите описание изображения здесь


Где вы получаете эту страницу?
Pacerier

@Pacerier Вы получите этот интерфейс, если php-apcв вашей системе установлен пакет.
Незнакомец

2

если вы запускаете fpm под Ubuntu, необходимо запустить приведенный ниже код (проверено на 12 и 14)

service php5-fpm reload

1

apc.ini

apc.stat = "1" заставит APC проверять скрипт на каждом запросе, чтобы определить, был ли он изменен. Если он был изменен, он перекомпилирует и кеширует новую версию.

Если этот параметр выключен, APC не будет проверять, что обычно означает, что для принудительной проверки APC файлов веб-сервер должен быть перезапущен, или кэш должен быть очищен вручную. Обратите внимание, что конфигурации веб-сервера FastCGI могут не очищать кэш при перезапуске. На рабочем сервере, где файлы сценариев редко изменяются, можно добиться значительного повышения производительности с помощью отключенной статистики.


1

В новом интерфейсе администратора APC есть опции для добавления / очистки пользовательского кэша и кэша кода операции. Одна интересная функция заключается в добавлении / обновлении / удалении каталога из кэша opCode

Документация администратора APC

введите описание изображения здесь


0

Хорошим решением для меня было просто больше не использовать устаревший пользовательский кеш после развертывания.

Если вы добавите префикс к каждому из ваших ключей, вы можете изменить префикс при изменении структуры данных записей кэша. Это поможет вам получить следующее поведение при развертывании:

  1. Не используйте устаревшие записи кэша после развертывания только обновленных структур
  2. Не очищайте весь кеш при развертывании, чтобы не замедлять работу вашей страницы
  3. Некоторые старые кэшированные записи могут быть повторно использованы после восстановления развертывания (если записи не были уже автоматически удалены)
  4. APC удалит старые записи в кэше после истечения срока действия ИЛИ в случае отсутствия места в кэше

Это возможно только для пользовательского кэша.


0

Создать файл APC.php

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

Запустите его из браузера.


2
Насколько я понимаю, экземпляр CLI не будет совместно использовать один и тот же сегмент кэш-памяти APC, так что это ничего не даст, кроме как очистить пустой, изолированный сегмент кэш-памяти APC.
А.Б. Кэрролл

в зависимости от дистрибутивов и конфигураций, кэш APC может иметь отдельный сегмент памяти, я обновил его для более общего решения.
Anshuman

0

Мой обходной путь для сборки Symfony с множеством экземпляров на одном сервере:

Шаг 1. Создайте триггер или что-то, чтобы установить флаг файла (например, команда Symfony), затем создайте marker file..

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

Шаг 2. В индексном файле при запуске добавить код очистки и удалить marker file.

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

Шаг 2. Запустите приложение.


-1

У нас была проблема с APC и символическими ссылками на символические ссылки на файлы - похоже, они игнорируют изменения в самих файлах. Каким-то образом выполнение касания самого файла помогло. Я не могу сказать, в чем разница между изменением файла и касанием его, но как-то это было необходимо ...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.