Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand and implement Symfony 3 Caching for Framework and Doctrine

We have a running application based on Symfony 3.2 (started with Symfony 2.3 back then) and Doctrine ORM 2.5 and it's awesome how things have evolved.

I read a lot about the new Symfony Cache component, the up's and down's of APC and APCU, opcache, the pull requests for chaching in Symfony etc... but to be very honest this time you lost me a bit.

So I kindly ask whether one can support me in 1) understanding and 2) implementing caching for a "standard" Symfony/Doctrine application in production.

Prerequisites/Assumptions

1) opcache should be enabled and active and cache anything bytecode related.

2) I currently don't have any requirement to cache my own app stuff. It's all about the framework caching like annotations, class maps, validations, ORM metadata etc.

2) Most developers don't want to deal with more than one caching provider, so be it APCu, xcache, redis, memcache or anything else. There might be very good reasons to have different ones for different tasks but let's stick to one to keep it simple.

Caching Options in a "standard" Symfony/Doctrine application in prod mode

1) Class Loading

We still have ApcClassLoader in place in app.php:

$loader = require __DIR__ . '/../app/autoload.php';
include_once __DIR__ . '/../var/bootstrap.php.cache';

$apcLoader = new ApcClassLoader('arcsf2', $loader);
$apcLoader->register(true);
$loader->unregister();

require_once __DIR__ . '/../app/AppCache.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$kernel = new AppCache($kernel);

There are only two options Symfony built-in to my understanding, ApcClassLoader and XcacheClassLoader. So this might be contradicting assumption 2 above.

Question:

Is it still needed/required/performing significantly better to have this caching ClassLoaders in place?

Or is it enough to use the standard app.php nowadays?

$loader = require __DIR__.'/../app/autoload.php';
include_once __DIR__.'/../var/bootstrap.php.cache';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();

2) Validation Caching

We still have this in our config_prod.yml:

framework:
validation:
    cache: validator.mapping.cache.doctrine.apc

Question:

To be very honest I have no idea, whether this is still valid with Symfony 3.2 and the new Cache component. And how to change it to a different Cache Provider if required. How could I change it to be 'up-to-date' with Symfony 3.2 Cache?

3) Doctrine Caching:

More or less the same question applies to the doctrine orm section in config_prod.yml:

doctrine:
orm:
    metadata_cache_driver: apc
    result_cache_driver: apc
    query_cache_driver: apc

Question:

Is this still the way to go? How to change this use the new Symfony Cache component - can this be done anyway?

4) New Options?

What about the new? options? of setting in config_prod.yml:

framework:
cache:
    app: cache.adapter.someProviderOrPool
    system: cache.adapter.someProviderOrPool

Question:

What kind of information is cached here, by whom and is this somehow replacing/extending some of the topics above?

To sum it up:

I want to basically change all my prod configs to be complient with Symfony 3.2 and I want to use redis for caching (replacing apc) wherever possible but I have absolutely no idea how and where to start.

****EDIT****

As well in this context how do Symfony Cache Component and DoctrineCacheBundle play together? Replacing? Adding up? Building Upon? Working together? Conflicting? Not Comparable?

like image 414
LBA Avatar asked Dec 02 '16 09:12

LBA


People also ask

What is Doctrine in Symfony?

Symfony provides all the tools you need to use databases in your applications thanks to Doctrine, the best set of PHP libraries to work with databases. These tools support relational databases like MySQL and PostgreSQL and also NoSQL databases like MongoDB.

What is cache in Symfony?

The Cache component provides features covering simple to advanced caching needs. It natively implements PSR-6 and the Cache Contracts for greatest interoperability. It is designed for performance and resiliency, ships with ready to use adapters for the most common caching backends.

How to cache clear in Symfony?

Clearing the Cache To clear the cache you can use the bin/console cache:pool:clear [pool] command. That will remove all the entries from your storage and you will have to recalculate all the values.

How do I know my doctrine version?

Check out the file vendor/doctrine/orm/lib/Doctrine/ORM/Version. php , there is a constant in there that shows the version. It's also accessible from a running app but this is easier.


1 Answers

Edit: Everything written here has been merged into Symfony's official documentation since then. You may want to check the up-to-date documentation instead

Use the OPcache byte code cache

OPcache stores the compiled PHP files to avoid having to recompile them for every request. There are some byte code caches available, but as of PHP 5.5, PHP comes with OPcache built-in. For older versions, the most widely used byte code cache is APC.

Configure OPcache for maximum performance

The default OPcache configuration is not suited for Symfony application, so it's recommended to change these settings as follows:

; php.ini

; maximum memory that OPcache can use to store compiled PHP files
opcache.memory_consumption=256M

; maximum number of files that can be stored in the cache
opcache.max_accelerated_files=20000

Don't check PHP timestamps

In production servers, PHP files should never change, unless a new application version is deployed. However, by default OPcache checks if cached files have changed their contents since caching them. This check introduces some overhead that can be avoided as follows:

; php.ini

; after each deploy, call `opcache_reset()` or restart the web server
; to empty the cache and regenerate the cached files. Otherwise you won't
; see the updates made in the application
opcache.validate_timestamps=0

Note

The OPcache is different for the web server and the command console. You cannot clear the web server OPcache by executing some command in your terminal. You either need to restart the web server or call the opcache_reset() function via the web server (i.e. by having this in a script that you execute over the web).

Configure the PHP realpath Cache

When a relative path is transformed into its real and absolute path, PHP caches the result to improve performance. The default config of this cache is not suited for applications that open many PHP files, such as Symfony. It's recommended to change these settings as follows:

; php.ini

; maximum memory allocated to store the results
realpath_cache_size=4096K

; save the results for 10 minutes (600 seconds)
realpath_cache_ttl=600

Configure the PHP realpath Cache

PHP uses an internal cache to store the result of mapping file paths to their real and absolute file system paths. This increases the performance for applications like Symfony that open many PHP files, especially on Windows systems.

By default, PHP sets a realpath_cache_size of 16K which is too low for Symfony. Consider updating this value at least to 4096K. In addition, cached paths are only stored for 120 seconds by default. Consider updating this value too using the realpath_cache_ttl option:

; php.ini

realpath_cache_size=4096K
realpath_cache_ttl=600

Optimize Composer Autoloader

The class loader used while developing the application is optimized to find new and changed classes. In production servers, PHP files should never change, unless a new application version is deployed. That's why you can use Composer's autoloader optimization to scan the entire application once and build a "class map", which is a big array of the locations of all the classes and it's stored in vendor/composer/autoload_classmap.php.

Execute this command to generate the class map at install time (and thus make it part of your deployment process too):

$ composer install --no-dev --optimize-autoloader --classmap-authoritative --apcu-autoloader

--no-dev Excludes the classes that are only needed in the development environment (e.g. tests).

--optimize-autoloader Dumps every PSR-0 and PSR-4 compatible class used in your application.

--classmap-authoritative Prevents Composer from scanning the file system for classes that are not found in the class map.

--apcu-autoloader You need to install APCu PHP extension to use this option. It will cache the classmap in APCu. It won't generate the classmap though, so you need to always use it with --optimize-autoloader

Tip

If your production server still uses the legacy APC PHP extension instead of OPcache, install the APCu Polyfill component in your application to enable compatibility with APCu PHP functions and unlock support for advanced Symfony features, such as the APCu Cache adapter.

Note

When using the APCu autoloader, if you add new classes, they will be found automatically and everything will work the same as before (i.e. no reason to "clear" the cache). However, if you change the location of a particular namespace or prefix, you'll need to flush your APCu cache. Otherwise, the autoloader will still be looking at the old location for all classes inside that namespace.

like image 79
Erdal G. Avatar answered Oct 14 '22 20:10

Erdal G.