首页 > 其他 > 详细

Using Redis for Doctrine Caching in Symfony2

时间:2015-11-01 19:49:38      阅读:458      评论:0      收藏:0      [点我收藏+]

Redis is an open source key-value cache and storage, which designed to be very fast since it uses in-memory datasets. Of course, you can persist your data by dumping it to the disk if you need it. Redis supports different data structures such as strings, lists, sets/sorted sets, hashes; atomic operations on these types, master-slave asynchronous replication, transactions, etc.

If you are using Doctrine with Symfony, Redis is a great tool to be used for caching, which is very easy to setup and it can drastically improve performance of your application.

Doctrine supports 3 types of caching:

  • Metadata Cache – cache annotations, table names, columns, relations.
  • Query Cache – cache the transformation of a DQL query to its SQL counterpart.
  • Result Cache – cache the results of the queries.

So let’s try to configure Doctrine to work with Redis for caching.

Redis installation

If you under OS X, you can use homebrew:

1 2 3 4
brew update brew install redis # start server redis-server 

For Ubuntu, you need to build it from sources:

1 2 3 4 5 6 7 8 9
wget http://download.redis.io/releases/redis-2.8.19.tar.gz tar xzf redis-2.8.19.tar.gz cd redis-2.8.19 make sudo make install cd utils sudo ./install_server.sh # start server service redis_6379 start 

If you’ve used default config, now redis is running on your machine on 6379 port.

SncRedisBundle bundle

We will use this great bundle to work with Redis inside our application. Note, that SncRedisBundle bundle can work with both Predis orPHPRedis libraries to communicate with Redis, so it’s your choice which one to use. I went with Predis.

Let’s add bundle itself and Predis as a needed dependency inside our composer.json and run composer install after that:

1 2
"predis/predis": "0.8.x-dev", "snc/redis-bundle": "1.1.x-dev" 

Activate bundle in app/AppKernel.php:

1 2 3 4 5 6 7 8 9 10
<?php public function registerBundles() {  $bundles = array(  // ...  new Snc\RedisBundle\SncRedisBundle(),  // ...  );  ... } 

Configure Redis client itself and set it to be used for Doctrine in app/config/config.yml:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
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 

In the same file, we need to enable metadata and query caching for Doctrine:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
doctrine:  dbal:  driver: %database_driver%  host: %database_host%  port: %database_port%  dbname: %database_name%  user: %database_user%  password: %database_password%  charset: UTF8  orm:  auto_generate_proxy_classes: %kernel.debug%  auto_mapping: true  # enable metadata caching  metadata_cache_driver: redis  # enable query caching  query_cache_driver: redis 

Result cache

In the most cases, you don’t need cache results from all of your queries, so let’s see how you can enable result cache for some individual one only. The best place to do it is inside of an entity repository class.

Let’s say we have Country entity with respective repository. In this repository, we have a method to find active countries and return a list with 3 items sorted by country’s sort field. Let’s add caching for the results of this method.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# use needed classes use Snc\RedisBundle\Doctrine\Cache\RedisCache; use Predis\Client;  class CountryRepository extends EntityRepository {  ...  public function findMostPopular($limit = 3)  {  # init predis client  $predis = new RedisCache();  $predis->setRedis(new Client());  # define cache lifetime period as 1 hour in seconds  $cache_lifetime = 3600;   return $this->getEntityManager()  ->createQuery(‘SELECT c FROM AcmeBundle:Country c ‘  . ‘WHERE c.active = 1 ORDER BY c.sort DESC‘)  ->setMaxResults($limit)  # pass predis object as driver  ->setResultCacheDriver($predis)  # set cache lifetime  ->setResultCacheLifetime($cache_lifetime)  ->getResult();  }  ... } 

That’s all. Now Doctrine will get countries data from the database for the first time, cache it in Redis for 1 hour and update it again after expiration.

Checking Doctrine cached values

Redis comes with redis-cli tool, which can be used to check cached values by running command KEYS *:

1 2 3 4 5
127.0.0.1:6379> KEYS * 1) "[AcmeBundle\\Entity\\Country$CLASSMETADATA][1]" 2) "DoctrineNamespaceCacheKey[]" 3) "[8358af94b8825e6f9413ed57f4ebc723][1]" 4) "[d16019c7f320a7d2389d8f279876190cdef26da4][1]" 

To see what contains individual cache entity, you can run GET key_string command.

Another great thing to check Doctrine cache is Symfony Profiler toolbar.

Using Redis for Doctrine Caching in Symfony2

原文:http://my.oschina.net/u/144160/blog/524609

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!