Symfony2: Flush XCache class cache on multiple instances on deployment

1.3k views Asked by At

app/console cache:clear isn't clearing XCache (or APC) which can lead to major problems after redeployment when we're using AppCache in app.php (e.g. bootstrap.php.cache and all other generated .cache. files are cached).

app.php (pretty default)

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

Our installation is distributed among 4 "application" servers so there's no way to reliably clear the cache on redeploys. What we would need is a way to tell all servers in our environment to flush their PHP/XCache. The APCBundle https://github.com/ornicar/ApcBundle seems to go that way but only works for APC.

A related problem is using the doctrine:cache:clear-query or clear-metadata commands. When we're using XCache as cache implementation for ORM metadata those commands actually don't flush anything at all even though they're writing "Clearing ALL Metadata cache entries Successfully deleted cache entries." -> a look into XCache admin reveals that everything is still there. This is actually anticipated since Symfony commands run in the PHP CLI environment. Again, the APC Bundle would flush the caches correctly.

a) is it a "bug" that the commands say that everything has been flushed or are we missing something? b) how could we reliably flush those caches on all our servers? c) has anyone written a similar solution like the APCBundle and can come up with best practices how to handle those issues? d) is it more feasible to restart each Apache after redeploy (no way but the hard way, our sysops would kill me for that idea)

1

There are 1 answers

3
Anton Babenko On

In case you have multiple instances you should use centralized cache storage (for example, Redis via SncRedisBundle to keep sessions, doctrine meta and query cache). In this way you will have to clear doctrine metadata or query cache once as the last step in your deployment process.

There are several deployment strategies, but in all of them restarting Apache will do the trick. Though there are many alternatives regarding how you do it :) You can swap instances which has old code with instances which has new code (drop and warmup caches). Alternatively (if you are using load-balancers), you can add new instances into group and remove old instances.

On my experience restarting php-fpm (I don't use Apache for several years now) will clear APC in no time and it works very stable, also there is no downtime at all.

Feel free to ask me if there are still questions.