Symfony2: очистить кеш класса XCache на нескольких экземплярах при развертывании

app/console cache:clear не очищает XCache (или APC), что может привести к серьезным проблемам после повторного развертывания, когда мы используем AppCache в app.php (например, bootstrap.php.cache и все другие сгенерированные файлы .cache. кэшируются).

app.php (почти по умолчанию)

$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
$loader = new \Symfony\Component\ClassLoader\XcacheClassLoader('sf2dc4', $loader);
$loader->register(true);
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$kernel = new AppCache($kernel);
Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Наша установка распределена между 4 серверами «приложений», поэтому нет возможности надежно очистить кеш при повторном развертывании. Что нам нужно, так это способ сообщить всем серверам в нашей среде, чтобы они сбросили свои PHP/XCache. APCBundle https://github.com/ornicar/ApcBundle, кажется, работает таким образом, но работает только для APC. .

Связанная проблема связана с использованием команд doctrine:cache:clear-query или clear-metadata. Когда мы используем XCache в качестве реализации кэша для метаданных ORM, эти команды на самом деле вообще ничего не очищают, даже если они пишут «Очистка ВСЕХ записей кэша метаданных, успешно удаленных записей кэша». -> просмотр администратора XCache показывает, что все по-прежнему там. На самом деле это ожидаемо, поскольку команды Symfony выполняются в среде PHP CLI. Опять же, пакет APC правильно очищает кэши.

а) это "баг", что в командах написано, что все сбросилось или мы что-то упускаем? б) как мы можем надежно очистить эти кеши на всех наших серверах? c) кто-нибудь написал аналогичное решение, такое как APCBundle, и может предложить лучшие методы решения этих проблем? г) более целесообразно перезапустить каждый Apache после повторного развертывания (никакой способ, кроме сложного, наши сисопы убьют меня за эту идею)


person Stefan    schedule 27.11.2013    source источник


Ответы (1)


Если у вас несколько экземпляров, вам следует использовать централизованное хранилище кеша (например, Redis через SncRedisBundle для хранения сеансов, метаданные доктрины и кеш запросов). Таким образом, вам придется очистить метаданные доктрины или кэш запросов один раз в качестве последнего шага в процессе развертывания.

Существует несколько стратегий развертывания, но во всех из них поможет перезапуск Apache. Хотя есть много альтернатив относительно того, как вы это делаете :) Вы можете поменять местами экземпляры со старым кодом на экземпляры с новым кодом (кеши сброса и прогрева). В качестве альтернативы (если вы используете балансировщики нагрузки) вы можете добавить новые экземпляры в группу и удалить старые экземпляры.

По моему опыту, перезапуск php-fpm (я не использую Apache уже несколько лет) мгновенно очистит APC, и он работает очень стабильно, а также вообще нет простоев.

Не стесняйтесь спрашивать меня, есть ли еще вопросы.

person Anton Babenko    schedule 27.11.2013
comment
да, на самом деле мы решили использовать Memcache в качестве слоя кэша результатов (он уже есть и отлично работает). Но для кэширования метаданных сущностей и преобразований DQL›SQL вполне достаточно xcache. Однако основная проблема заключается в нашем кеше классов: в нем будут храниться старые определения, если мы его не сбросим. Я не думаю, что вы можете (должны) кэшировать код операции в Redis, не так ли :)? - person Stefan; 27.11.2013
comment
Тогда я бы перезапустил php-fpm (или Apache в вашем случае). Конечно, нет Redis для опкода :) - person Anton Babenko; 28.11.2013
comment
скажите этому нашему администратору, который все еще считает, что вам не следует перезапускать веб-сервер :( - person Stefan; 28.11.2013