Mise en place de Memcached dans un projet Symfony 2 avec le Bundle LswMemcacheBundle

Installation et mise en place du bundle LswMemcacheBundle dans un projet Symfony 2.

Publié le 04/08/2015

1 - Installation de memcached

apt-get install memcached php5-memcache

2 - Installation du Bundle

Ajouter la ligne suivante à votre fichier composer.json :

"leaseweb/memcache-bundle": "*"

Faire un php composer.phar install, cleaner les caches et les droits.

Enregistrer le bundle dans le fichier /app/AppKernel.php en ajoutant la ligne suivante :

new Lsw\MemcacheBundle\LswMemcacheBundle(),

3 - Paramétrage du bundle

Dans le fichier /app/config/config.yml ajouter la section suivante :


# Memcache
lsw_memcache:
    session:
        pool: default
    pools:
        default:
            servers:
              - { host: localhost, tcp_port: 11211 }

4 - Exemple d'implémentation

Pour l'exemple on va se baser sur celui qui m'a servi sur ce site pour la rubrique tutorial.

Dans le model je vais avoir deux entités liées Tutorial et Category. Je vais effectuer dans le repository de Tutorial une requête qui appel tous les articles et leurs catégories par date décroissante.

Dans le controller je vais stocker la requête dans un objet memcache et solliciter celui-ci pour envoyer mes données vers la vue. Je vais donc faire un économie de requête pendant la durée de vie de mon cache.

Repository :


public function getAllTutorialsByDate()
	{
		$qb = $this->createQueryBuilder('t');

		$qb
			->addSelect('t')
			->leftJoin('t.categoryTutorial', 'ct')
			->orderBy('t.createdAt', 'DESC')
		;

		return $qb->getQuery()->getResult();
	}

Controller :


public function tutorialsPageAction()
    {
        // call entity manager
        $em = $this->getDoctrine()->getManager();

        // retrieve tutorials page
        $tutorialPage = $em->getRepository('JobmanagerMainBundle:Page')
                            ->find(7);

        // init memcache object
        $cache = $this->get('memcache.default');

        // MEMCACHE
        if ($cache->get('tutorial_list')) {
            return $this->render('JobmanagerCmsBundle:Page:tutorials.html.twig', array(
                'tutorialPage' => $tutorialPage,
                'tutorials' => $cache->get('tutorial_list')
            ));
        } else {
            // retrieve tutorials
            $tutorials = $em->getRepository('JobmanagerMainBundle:Tutorial')
                            ->getAllTutorialsByDate();
	    $cache->delete('tutorial_list');
            $cache->set('tutorial_list', $tutorials, false, 3600);


            // send view
            return $this->render('JobmanagerCmsBundle:Page:tutorials.html.twig', array(
                'tutorialPage' => $tutorialPage,
                'tutorials' => $cache->get('tutorial_list')
            ));
        }
    }

Dans le cas où le cache est situé sur la même machine que le serveur MySQL, le gain de performance n'est pas visible sur des petites db.

Sources :