John
John

Reputation: 121

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?

Upvotes: 5

Views: 12577

Answers (2)

Tebe
Tebe

Reputation: 171

Nov 7, 2018:

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 ;)

Upvotes: 9

Michael Käfer
Michael Käfer

Reputation: 1796

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 { ... }

Upvotes: 9

Related Questions