3

We are attempting to deploy new PHP code via Capistrano while running Opcache.

Capistrano creates a new deploy directory each time you deploy, then adjusts a symlink so that the webserver points to the new directory. Because Opcache caches by the real path of the file, that means that the newly deployed version of a site is cached completely separately from the old.

The problem we are running into is that Opcache runs out memory because each new deploy causes the full code base to be cached, and old code is never evicted. We could call opcache_reset(), but when the cache is reset, we briefly get 500 errors when the caches stampede. (We would also have the same errors if we tried to launch a new deploy without warming up the cache.)

Is there a better way to handle this? Some way to launch the new code while not filling up opcache until it runs out of memory (or empties itself because it has too many files) that allows us to avoid calling opcache_reset() on the live site? We are using (or trying to transition to, anyway) Nginx as our web server with PHP-FPM handling the PHP requests.

Karptonite
  • 1,490
  • 2
  • 14
  • 30
  • 1
    As I explained on T0xicCode's answer the old version's op_arrays are dead space until reclaimed by a reset. The trick is to have the cache large enough to hold two copies of the app and then do the reset during the graveyard shift part of the daily load cycle. – TerryE Jan 14 '15 at 16:22

1 Answers1

1

An option would be to call opcache_invalidate for each of the files in the old version of the site at the end of the deployment. You could prevent cache stampede by including the file following the invalidation.

A second option would be to setup fpm to have multiple pools, and to restart them one by one (they'll start with a clean opcache). You'll somewhat prevent the cache stampede only one server will have a clean cache at any given time, and the application will stay up because nginx will be able to balance the load on the various pool.

Another option is to delete the old versions of the script, so that opcache clears them from the cache once the revalidate_freq has passed, forcing it to load the new files from the filesystem.

T0xicCode
  • 4,583
  • 2
  • 37
  • 50
  • 2
    Using invalidate doesn't help in this usecase as OPcache doesn't employ a resource reuse model. The space is dead until a reset is executed or triggered by the ini settings. – TerryE Jan 14 '15 at 16:19