Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to enable second cache level in doctrine?

I enabled second cache level in my config file:

  orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        second_level_cache:
            region_cache_driver:
                type:                 array
                host:                 ~
                port:                 ~
                instance_class:       ~
                class:                ~
                id:                   ~
                namespace:            ~
                cache_provider:       ~
            region_lock_lifetime: 600
            log_enabled:          true
            region_lifetime:      0
            enabled:              true

in my entity that need to cache, add new annotation (Cache) like:

/**
 * Entity
 *
 * @ORM\Table(name="entity")
 * @ORM\Cache(usage="READ_ONLY", region="entity_cache")
 */
class Entity
{

/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
  private $id;

}

But show it now:
enter image description here

so, first what do mean cache hits, cache misses and cache puts? and second what happened now and how can cache my entity?

like image 721
John Avatar asked Dec 11 '22 12:12

John


2 Answers

Firstly here's an important warning from Doctrine:

"The second level cache functionality is marked as experimental for now. It is a very complex feature and we cannot guarantee yet that it works stable in all cases."

So,

"how can cache my entity?"

  1. You need to set up a cache provider (redis, memcached, so on)
  2. add doctrine and cache provider dependencies with composer require
  3. configure cache provider
  4. enable second lvl cache in app/config.yml

    doctrine:
      orm:
        second_level_cache:
          enabled: true
    
  5. You should specify caching regions for each type of data (entity data, collecion data or query data) too:

    regions:
      entity_that_rarely_changes:
        lifetime: 86400
        cache_driver: redis
        type: service
        id: snc_second_level_cache
    
  6. Config your entity/entities:

    • Choose a caching mode ("readonly" is the default one)
    • and a region (see above)

      /**
      * @Cache(usage="READ_ONLY", region="my_entity_region")
      */
      class MyEntity 
      
  7. And finally: your queries:

    $em->persist(new MyEntity($name));
    $em->flush();
    $em->clear(); // clear em
    $item1  = $em->find('MyEntity', 1); // Retrieve item from cache
    $item1->setName("newname");
    $em->persist($item1);
    $em->flush(); // update row and update cache
    $em->clear(); // clear em
    $item2  = $em->find('MyEntity', 1); // Retrieve item from cache
    

"what do mean cache hits, cache misses and cache puts"

  • hits: the item is in the (declared region's) cache, so u dont need to query the db
  • missed: the item is not in the (declared region's) cache, so u need to query the db
  • puts: how many cacheable entries put in the cache (region).

You should check your Entity cache region paramter in

@Cache(usage="READ_ONLY", region="my_entity_region")

and your config yml file, for example:

regions:
  my_entity_region:
    cache_driver: redis
    lifetime: 3600

If (the names of) the regions are different, the entity cache will be "missed" always.

I use a lot of external source, like Doctrine 2 documentation. You should do the same ;)

like image 55
Tebe Avatar answered Dec 13 '22 01:12

Tebe


Tested on Symfony 5.1, you do not need to add any bundle or package. All you have to do is something close to:

# config/packages/dev/cache.yaml
framework:
    cache:
        app: cache.adapter.redis
        default_redis_provider: redis://localhost
# config/packages/dev/doctrine.yaml
doctrine:
    orm:
        second_level_cache:
            enabled: true
            region_cache_driver:
                type: pool
                pool: doctrine.second_level_cache_pool
framework:
    cache:
        pools:
            doctrine.second_level_cache_pool:
                adapter: cache.app

And on your entities for example:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Cache
 */
class Category { ... }
like image 26
Michael Käfer Avatar answered Dec 13 '22 00:12

Michael Käfer