John
John

Reputation: 1655

Redis store values under one key or multiple keys

Hey All ok so I have written a API in Symfony2 Framework, To enhance my API I installed and configured Redis bundle Redis.

config.yml:

    # Doctrine Configuration
doctrine:
    dbal:
        driver:   pdo_mysql
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true

#        enable metadata caching
        metadata_cache_driver: redis
#        enable query caching
        query_cache_driver: redis

snc_redis:
# configure predis as client
clients:
    default:
        type: predis
        alias: default
        dsn: redis://localhost
    doctrine:
        type: predis
        alias: doctrine
        dsn: redis://localhost
# configure doctrine caching
doctrine:
    metadata_cache:
        client: doctrine
        entity_manager: default
        document_manager: default
    result_cache:
        client: doctrine
        entity_manager: [default]
    query_cache:
        client: doctrine
        entity_manager: default

After reading some Redis and Doctrine Docs in my Repository I came up with this code:

    <?php

namespace BooksApi\BookBundle\Repositories;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query\QueryException;

use Snc\RedisBundle\Doctrine\Cache\RedisCache;
use Predis\Client;

class FetchBookRepository
{
    /**
     * @var EntityManager
     */
    public $em;

    /**
     * @param EntityManager $entityManager
     */
    public function __construct(
        EntityManager $entityManager
    ){
        $this->em = $entityManager;
    }

    /**
     * @param $id
     * @return null|object
     * @throws QueryException
     */
    public function fetchBook($id)
    {

        $predis = new RedisCache();
        $predis->setRedis(new Client);
        $cacheId = 'FetchBook' . '-' . $id;
        $cacheLifetime = 3600;

        $book = $this->em->getRepository('BooksApiBookBundle:BooksEntity')
            ->createQueryBuilder('book')
            ->where('book.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->setResultCacheDriver($predis)
            ->setResultCacheLifetime($cacheLifetime)
            ->setResultCacheId($cacheId);
        $result = $book->getSingleResult();

        return $result;
    }
}

Now every Book entity i fetch from the DB it gets it unique Key $cacheId = 'FetchBook' . '-' . $id;, So if ie there is 1000+ books there will be a key => value entry for each, But if allow redis to store all books values under one key $cacheId = 'FetchBook' what impact does this have...?

And what you you guys think of my set up query is there a better way of doing things...?

Redis-Cli output:

1) "[b1f50028ac0187db185a0f52f654e555][1]"
2) "[FetchBook][1]"
3) "[BooksApi\\BookBundle\\Entity\\BooksEntity$CLASSMETADATA][1

Upvotes: 2

Views: 2265

Answers (1)

Robert
Robert

Reputation: 20286

What you look for is named second level cache. It is experimental feature and it is not stable yet so if you decide to use it, then use it carefully.

From doc:

The Second Level Cache is designed to reduce the amount of necessary database access. It sits between your application and the database to avoid the number of database hits as much as possible.

When turned on, entities will be first searched in cache and if they are not found, a database query will be fired and then the entity result will be stored in a cache provider.

Btw you don't need to define whole new cache object for each query just use

->useQueryCache(true);
->useResultCache(true);

methods. You can also do your own caching via redis service.

Upvotes: 1

Related Questions