Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystifying cache in Doctrine ORM (v2)

Demystifying cache in Doctrine ORM (v2)

Applications should be fast regardless of any cache system. However, sometimes we do need to cache data in order to optimise things and deliver a fast response to the clients.
This talk covers the different types of cache offered Doctrine ORM (metadata, query, result set, and second level cache), how they work together with the Unit of Work and what we should know before caching all the things.

Luís Cobucci

May 11, 2018
Tweet

More Decks by Luís Cobucci

Other Decks in Technology

Transcript

  1. Template Message Customer Campaign 1 1 1 * * *

    INSERT INTO customer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @customer_id = LAST_INSERT_ID();
  2. Template Message Customer Campaign 1 1 1 * * *

    INSERT INTO customer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @customer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”);
  3. Template Message Customer Campaign 1 1 1 * * *

    INSERT INTO customer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @customer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”);
  4. Template Message Customer Campaign 1 1 1 * * *

    INSERT INTO customer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @customer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”); INSERT INTO message (campaign_id, customer_id, sent)
 VALUES (LAST_INSERT_ID(), @customer_id, FALSE);
  5. Template Message Customer Campaign 1 1 1 * * *

    INSERT INTO customer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @customer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”); INSERT INTO message (campaign_id, customer_id, sent)
 VALUES (LAST_INSERT_ID(), @customer_id, FALSE); Don’t forget to use a transaction!
  6. declare(strict_types=1); $customer = new Customer('Luís Cobucci', '[email protected]');
 $template = new

    Template('Template 1', 'blah… blah… blah…');
 $campaign = new Campaign($template, 'Test', 'blah… blah… blah…');
 $message = new Message($campaign, $customer);
 
 $entityManager->persist($customer); $entityManager->persist($template); $entityManager->persist($campaign); $entityManager->persist($message); $entityManager->flush();
  7. declare(strict_types=1); $customer = $entityManager->find('Customer', 2); $campaign = $entityManager->find('Campaign', 1);
 


    $entityManager->persist(new Message($campaign, $customer)); $entityManager->flush();
  8. “ a hardware or software component that stores data so

    future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere. Cache (computing) - Wikipedia
  9. Our software Cache External API 2. Cache miss 3. Give

    me data 1. Give me “external.result”
  10. Our software Cache External API 2. Cache miss 3. Give

    me data 4. There you go 1. Give me “external.result”
  11. Our software Cache External API 2. Cache miss 1. Give

    me “external.result” 3. Give me data 4. There you go 5. Store “external.result”
  12. Our software Cache External API 2. Cache miss 1. Give

    me “external.result” 3. Give me data 4. There you go 5. Store “external.result” 6. Stored!
  13. Our software Cache External API 2. Cache hit! 1. Give

    me “external.result” When should we invalidate the cache?
  14. “ There are two hard things in Computer Science: cache

    invalidation, naming things, and off-by-one errors Common sense
  15. /** @ORM\Entity */ class Customer
 {
 /** 
 * @ORM\Id


    * @ORM\GeneratedValue 
 * @ORM\Column(type="integer")
 */ private $id;
 
 /** @ORM\Column(type="string") */
 private $name;
 
 /** @ORM\Column(type="string") */
 private $email; }
  16. /** @ORM\Entity */ class Customer
 {
 /** 
 * @ORM\Id


    * @ORM\GeneratedValue 
 * @ORM\Column(type="integer")
 */ private $id;
 
 /** @ORM\Column(type="string") */
 private $name;
 
 /** @ORM\Column(type="string") */
 private $email; } ClassMetadata
  17. SELECT customer FROM Customer customer; SELECT
 c0.id AS id_0,
 c0.name

    AS name_1, c0.email AS email_2,
 FROM customer c0;
  18. declare(strict_types=1); $builder = $entityManager->createQueryBuilder()
 ->select(‘customer’) ->from(Customer::class, ‘customer'); if (isset($params[‘email’])) {

    $builder->where(‘customer.email = :email’)
 ->setParameter(‘email’, $params[‘email’]); } $query = $builder->getQuery();
 $result = $query->getResult();
  19. $query = 'SELECT COUNT(m) FROM Message m WHERE m.user =

    :user'; 
 $count = $entityManager->createQuery($query)
 ->setParameter('user', 1)
 ->getSingleScalarResult();
  20. $query = 'SELECT COUNT(m) FROM Message m WHERE m.user =

    :user'; 
 $count = $entityManager->createQuery($query)
 ->setParameter('user', 1)
 ->useResultCache(true, 3600)
 ->getSingleScalarResult();
  21. declare(strict_types=1); use Doctrine\Common\Cache\RedisCache; use Doctrine\ORM\Cache as L2C; use Doctrine\ORM\Configuration; $level2Cache

    = new RedisCache(); $level2Config = new L2C\CacheConfiguration(); $level2Config->setSecondLevelCacheEnabled( new L2C\DefaultCacheFactory( new L2C\RegionsConfiguration(), $level2Cache ) ); $configuration = new Configuration(); // … $configuration->setSecondLevelCacheEnabled(true); $configuration->setSecondLevelCacheConfiguration($level2Config);
  22. /**
 * @ORM\Entity
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE")
 */ class Message
 {
 //

    …
 
 /**
 * @ORM\ManyToOne(targetEntity="Customer") * @ORM\Cache(usage="READ_ONLY") */
 private $customer; 
 // …
 }
  23. $query = ‘SELECT m FROM Message m WHERE m.customer =

    :id’; 
 $messages = $entityManager->createQuery($query)
 ->setParameter(‘id', 1)
 ->setCacheable(true)
 ->getResult();