On Github gianarb / symfonyday-2015
SymfonyDay 2015
Member of:
Zend Framework Integration
Doctrine Team
There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
ORM is one of this libraries
it is a standalone projec to manage cache
fetch($id) - fetches an entry from the cache
contains($id) - test if an entry exists in the cache
save($id, $data, $lifetime) - puts data into the cache
delete($id) - deletes a cache entry
it supports different adapters
APC
Memcache
Memcached
Redis
Your implementation
EntityManager
UnitOfWork
Metadata Drivers
DQL
Repositories
Second Level Cache
data about your data structure
# app/config/config.yml doctrine_cache: providers: metadata_cache: aliases: [doctrine.orm.default_metadata_cache] file_system: directory: "%kernel.cache_dir%/doctrine/metadata" orm: metadata_cache_driver: cache_provider: metadata_cache
Caches the transformation of a DQL query to its SQL counterpart.
# app/config/config.yml doctrine_cache: providers: query_cache: aliases: [doctrine.orm.default_metadata_cache] file_system: directory: "%kernel.cache_dir%/doctrine/metadata" orm: query_cache_driver: cache_provider: query_cache
$usersCount = $entityManager ->createQuery('SELECT COUNT(u) FROM User u') ->useResultCache(true) ->setResultCacheId('count_user'); ->setResultCacheLifeTime(7200) ->getResult();
Cache ID dependes from query and PARAMS!
Doctrine >= 2.5
The Second Level Cache is designed to reduce the amount of necessary database access
Tries to reduce the gap between SQL and NoSQL database
Reduce gap?!
App\FetchSingleEvent Method Name Iterations Average Time Ops/second ------------ ------------ ----------------- ------------- withMongoDB: [ 1,000] [0.0002602758408] [3,842.07769] withMySQL : [ 1,000] [0.0003527779579] [2,834.64422] withMySqli : [ 1,000] [0.0003824789524] [2,614.52295]
The ORM tries to load an entity from the cache first
If it is not there, it fetches from the database, then caches the entity
Region
Second level cache is organized into regions - each region has its own namespace and lifetime parameters
Each entity is assigned to a region
Caching mode
Defines how your entities are cached
READ_ONLY: Perfect for immutable data, simple to manage.
READ_WRITE: doctrine locks the cache internally
NONSTRICT_READ_WRITE: perfect for sites with rare updates, no lock
it something like this
[ "from Person as p where p.parent.id=? and p.firstName=?", [ 1 , "Joey"] ] -> [ 2 ] ]
it caches only entity identifier and values
[ 'region_name:entity_1_hash' => [ 'id'=> 1, 'name' => 'FooBar', 'associationName'=>null ] ];
This is our use case
This is our use case
there are worst cases
+49% for free
In dev Mode 98% pages load in ~744ms
Metadata and queries in cache (apc) 98% pages load in ~366ms
Internal PHP server
Are you sure that is all a problem of time?
not all that glitters is gold
cache configuration is your responsability, it doesn't know the application flow