16/09/2018 - MEMCACHED, SYMFONY, REDIS
Bu örnek, Symfony uygulamalarında Memcached'i "cache pool" olarak nasıl kullanabileceğimizi göstermektedir. Belirli havuzdaki tüm önbellekleri, diğer havuzlarda bulunan önbellek öğelerine dokunmadan tek seferde temizleyebilirsiniz. Havuz dışı bir versiyonu daha var ama bu tercih edilen yaklaşımdır.
Eğer Redis'i kullanmak istiyorsanız, yapmanız gereken tek şey aşağıdaki konfigürasyonu eklemektir. Daha sonra sudo apt-get install redis-server
ve sudo apt-get install php7.2-redis
komutlarını çalıştırdıktan sonra web/php servislerini yeniden başlatın.
framework:
cache:
default_redis_provider: 'redis://localhost:6379'
pools:
app.cache.countries:
adapter: cache.adapter.redis
public: false
default_lifetime: 60
$ sudo apt-get install memcached
$ sudo apt-get install -y libapache2-mod-php
$ sudo apt-get install -y php7.2-memcached
$ sudo systemctl restart nginx
$ sudo service php7.2-fpm restart
$ composer require symfony/cache
# Clear cache for given pool only in terminal
$ bin/console cache:pool:clear app.cache.countries
$ bin/console cache:pool:clear app.cache.products
# Delete a cache from given pool in terminal
$ bin/console cache:pool:delete app.cache.countries key
framework:
cache:
default_memcached_provider: 'memcached://localhost:11211'
pools:
app.cache.countries:
adapter: cache.adapter.memcached
public: false
default_lifetime: 60
app.cache.products:
adapter: cache.adapter.memcached
public: false
default_lifetime: 120
services:
App\Controller\CountryController:
arguments:
$cachePool: '@app.cache.countries'
tags: ['controller.service_arguments']
App\Controller\ProductController:
arguments:
$cachePool: '@app.cache.products'
tags: ['controller.service_arguments']
declare(strict_types=1);
namespace App\Controller;
use App\Util\CacheInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* @Route("/countries")
*/
class CountryController
{
private $cachePool;
private $cacheUtil;
public function __construct(
MemcachedAdapter $cachePool,
CacheInterface $cacheUtil
) {
$this->cachePool = $cachePool;
$this->cacheUtil = $cacheUtil;
}
/**
* @Route("/save-item", methods={"GET"})
*/
public function saveItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->saveItem($this->cachePool, 'key', 'country'));
}
/**
* @Route("/get-item", methods={"GET"})
*/
public function getItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->getItem($this->cachePool, 'key'));
}
/**
* @Route("/delete-item", methods={"GET"})
*/
public function deleteItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->deleteItem($this->cachePool, 'key'));
}
/**
* @Route("/delete-all", methods={"GET"})
*/
public function deleteAll(): JsonResponse
{
return new JsonResponse($this->cacheUtil->deleteAll($this->cachePool));
}
}
declare(strict_types=1);
namespace App\Controller;
use App\Util\CacheInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* @Route("/products")
*/
class ProductController
{
private $cachePool;
private $cacheUtil;
public function __construct(
MemcachedAdapter $cachePool,
CacheInterface $cacheUtil
) {
$this->cachePool = $cachePool;
$this->cacheUtil = $cacheUtil;
}
/**
* @Route("/save-item", methods={"GET"})
*/
public function saveItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->saveItem($this->cachePool, 'key', 'product'));
}
/**
* @Route("/get-item", methods={"GET"})
*/
public function getItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->getItem($this->cachePool, 'key'));
}
/**
* @Route("/delete-item", methods={"GET"})
*/
public function deleteItem(): JsonResponse
{
return new JsonResponse($this->cacheUtil->deleteItem($this->cachePool, 'key'));
}
/**
* @Route("/delete-all", methods={"GET"})
*/
public function deleteAll(): JsonResponse
{
return new JsonResponse($this->cacheUtil->deleteAll($this->cachePool));
}
}
declare(strict_types=1);
namespace App\Util;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
interface CacheInterface
{
public function saveItem(MemcachedAdapter $cachePool, string $key, string $value): bool;
public function getItem(MemcachedAdapter $cachePool, string $key): ?string;
public function deleteItem(MemcachedAdapter $cachePool, string $key): bool;
public function deleteAll(MemcachedAdapter $cachePool): bool;
}
declare(strict_types=1);
namespace App\Util;
use App\Exception\CacheException;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
class MemcachedUtil implements CacheInterface
{
public function saveItem(MemcachedAdapter $cachePool, string $key, string $value): bool
{
$item = $this->fetch($cachePool, $key);
$item->set($value);
return $cachePool->save($item);
}
public function getItem(MemcachedAdapter $cachePool, string $key): ?string
{
$result = null;
$item = $this->fetch($cachePool, $key);
if ($item->isHit()) {
$result = $item->get();
}
return $result;
}
public function deleteItem(MemcachedAdapter $cachePool, string $key): bool
{
return $cachePool->deleteItem($key);
}
public function deleteAll(MemcachedAdapter $cachePool): bool
{
return $cachePool->clear();
}
private function fetch(MemcachedAdapter $cachePool, string $key): CacheItemInterface
{
try {
return $cachePool->getItem($key);
} catch (InvalidArgumentException $e) {
throw new CacheException($e->getMessage());
}
}
}
declare(strict_types=1);
namespace App\Exception;
use RuntimeException;
class CacheException extends RuntimeException
{
}