If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeYay! The var/cache
directory does not need to be writable and our life is simple and all our cache dreams are fulfilled. Well actually, we can do more with caching to make our site screaming fast. Zoom!
First, let's install apcu
- this should be a bit faster than OpCache. I'll do this during provision. Open up playbook.yml
. Down a bit, yep! Add a new package: php-apcu
:
- hosts: webserver | |
... lines 3 - 33 | |
tasks: | |
... lines 35 - 66 | |
- name: Install PHP packages | |
become: true | |
apt: | |
... lines 70 - 71 | |
with_items: | |
... lines 73 - 78 | |
- php-apcu | |
... lines 80 - 172 |
This package is named a bit different than the others.
Let's get the provision started - use playbook.yml
and add -l aws
to only provision the aws host:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini --ask-vault-pass -l aws
Use beefpass
for the password.
There's one other way we can boost performance. Open app/config/config_prod.yml
:
... lines 1 - 3 | |
#doctrine: | |
# orm: | |
# metadata_cache_driver: apc | |
# result_cache_driver: apc | |
# query_cache_driver: apc | |
... lines 9 - 26 |
See those Doctrine caches? Uncomment the first and third, and change them to apcu
, which our server will now have! Woo!
... lines 1 - 3 | |
doctrine: | |
orm: | |
metadata_cache_driver: apcu | |
# result_cache_driver: apc | |
query_cache_driver: apcu | |
... lines 9 - 26 |
The metadata_cache_driver
caches the Doctrine annotations or YAML mapping... this is not stuff we need to be parse on every request. The query_cache_driver
is used when querying: it caches the translation from Doctrine's DQL into SQL. This is something that does not need to be done more than once.
So... now... I have the same question as before: do we need to clear this cache on each deploy? Nope! Internally, Symfony uses a cache namespace for Doctrine that includes the directory of our project. Since Ansistrano always deploys into a new releases/
directory, each deploy has its own, unique namespace.
When provisioning finishes, commit the new config changes:
git add -u
git commit -m "Doctrine caching"
Push them!
git push origin master
Now, deploy the site:
ansible-playbook ansible/deploy.yml -i ansible/hosts.ini --ask-vault-pass
While we're waiting, find the server again and run:
php -i | grep apcu
Yes! Now APCu is installed and working. Without doing anything else, Symfony's cache.system
service is already using it. And when the deploy finishes, thanks to the Doctrine caching, we should have the fastest version of our site yet.
Except... for one more, fascinating cache issue. Actually, let's not call it a cache issue. Let's call it a cache opportunity!
Hey ahmedbhs !
Excellent questions!
> Why we don't activate `result_cache_driver`
This activates the cache on a separate, optional caching system where Doctrine can cache the results of a query. Even if you activate this config, you still need to activate the cache on any queries where you want this - https://doctrine2.readthedo...
I don't use this feature because I just use Symfony's cache service whenever I want to cache anything (whether that's the result of something from the database or something else).
> what'is the difference between metadata_cache_driver and query_cache_driver?
It's subtle. The "metadata cache" basically caches the annotations that you have on your entities. The query cache caches the transformation from the DQL queries (which are also used with the query builder) into SQL. Both are things that it makes 100% sense to cache and not reset that cache until something in your code changes (e.g. on the next deploy).
> For how can't install apcu, do you think using pool cache is a good idea ?
What do you mean by a pool cache? Are you referring to Symfony's cache pools? If so, absolutely. The cache config I show here is a bit out-of-date. It works, but we've made it easier in newer versions of DoctrineBundle to use Symfony's cache instead. You can see a nice example in the recipe for DoctrineBundle - this is the config file for the "prod" environment: https://github.com/symfony/...
Cheers!
// composer.json
{
"require": {
"php": ">=5.5.9",
"doctrine/doctrine-bundle": "^1.6", // 1.6.8
"doctrine/orm": "^2.5", // v2.7.2
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"sensio/distribution-bundle": "^5.0.19", // v5.0.20
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
"symfony/monolog-bundle": "^3.1.0", // v3.1.0
"symfony/polyfill-apcu": "^1.0", // v1.4.0
"symfony/swiftmailer-bundle": "^2.3.10", // v2.6.3
"symfony/symfony": "3.3.*", // v3.3.5
"twig/twig": "^1.0||^2.0", // v1.34.4
"doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.1
"predis/predis": "^1.1", // v1.1.1
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.6
"symfony/phpunit-bridge": "^3.0", // v3.3.5
"doctrine/data-fixtures": "^1.1", // 1.3.3
"hautelook/alice-bundle": "^1.3" // v1.4.1
}
}
# ansible/requirements.yml
-
src: DavidWittman.redis
version: 1.2.4
-
src: ansistrano.deploy
version: 2.7.0
-
src: ansistrano.rollback
version: 2.0.1
Why we don't activate `result_cache_driver` ? what'is the difference between metadata_cache_driver and query_cache_driver ? For how can't install apcu, do you think using pool cache is a good idea ?