27/05/2017 - SYMFONY
Bu örneğimizde redisi symfony uygulamasında nasıl kullanacağımızı göreceğiz. Örnekte sadece temel özellikleri kullanacağım ama siz isterseniz genişletebilirsiniz. Komutların listesine buradan ve dökümantasyona da buradan ulaşabilirsiniz.
Redis ön bellek olarak bilinen bir veri depolama unitesidir (NoSQL veritabanı olarakta anılır). Memcached'in aksine, mevcut durumunu istenildiği zaman diske yazabildiği için, bilgisayar yeniden başlatmalarda veri kaybı olmaz. Veriler ön bellekte (RAM) tutulduğu için, veri toplamı RAM toplamından fazla olamaz. Bu günlerde çoğu kişi, performans nedeniyle memcached ve MongoDB yerine redis kullanmayı tercih ediyor. Redis strings, hashes, lists, sets, sorted sets vs. veri tiplerine sahip ama memcached sadece strings kullanıyor.
list
gibidir ama sıralı olmadığı gibi, her element sadece bir kez bulundurulur.set
gibidir ama değerler set
olarak tutulurlar ve sıralıdırlar/puanlandırılmışlardır. Her üyenin bir puanı vardır ve set
alanları küçükten büyüğe sıralanmışlardır.http://192.168.50.10:8081/app_dev.php/redis/set?key=a&value=1
http://192.168.50.10:8081/app_dev.php/redis/set?key=a&value=1&ttl=10
http://192.168.50.10:8081/app_dev.php/redis/get?key=a
http://192.168.50.10:8081/app_dev.php/redis/ttl?key=a
http://192.168.50.10:8081/app_dev.php/redis/persist?key=a
http://192.168.50.10:8081/app_dev.php/redis/delete?key=a
http://192.168.50.10:8081/app_dev.php/redis/expire?key=a&ttl=10
$ sudo apt-get update
$ sudo apt-get install redis-server
$ sudo service redis-server status
Konfigürasyon dosyası /etc/redis/redis.conf
yolundadır.
$ ps aux | grep redis
redis 31748 0.1 0.3 38576 7248 ? Ssl 13:42 0:00 /usr/bin/redis-server 127.0.0.1:6379
vagrant 31917 0.0 0.0 10472 904 pts/0 R+ 13:47 0:00 grep --color=auto redis
Yukarıda da gördüğümüz gibi, host 127.0.0.1
ve port ise 6379
'dir. Redis komut satırına ulaşmak için aşağıdaki komutu kullanabilirsiniz. Redis hakkında bilgi almak için info
komutunu kullanın.
$ redis-cli
127.0.0.1:6379>
127.0.0.1:6379> monitor
1495812054.054517 [0 127.0.0.1:59164] "SET" "a" "1" # Persistent
1495812054.054517 [0 127.0.0.1:59164] "SETEX" "b" "10" "2" # Expire in 10 seconds
Yukarıda da gördüğümüz gibi, sisteme daha önceden a
ve b
olmak üzere iki tane anahtar-değer bilgisi girdim. Sistemde o an için çalıştırılan tüm komutları anlık olarak görmek isterseniz monitor
komutunu kullanabilirsiniz.
127.0.0.1:6379> scan 0
1) "0"
2) 1) "a"
3) 2) "b"
127.0.0.1:6379> GET a
"1"
127.0.0.1:6379> TTL a
(integer) -1 # Persistent
127.0.0.1:6379> GET b
"2"
127.0.0.1:6379> TTL b # Run this command 3 seconds later
(integer) 7 # 7 seconds to expire
127.0.0.1:6379> TTL b # Run this command 20 seconds later
(integer) -2 # Expired
Eğer TTL'i belirlemezseniz, yarattığınız anahtarın zamanı hiçbir zaman dolmayacak, yani otomatik olarak TTL -1
olarak atanacaktır. Buda teknik olarak "kalıcı" anahtar anlamına gelir.
$ sudo apt-get install php5-redis
$ sudo service apache2 restart
Composer.json dosyasına "ext-redis": "*"
ekleyin ve composer update ext-redis
komutunu çalıştırın.
parameters:
redis.host: 127.0.0.1
redis.port: 6379
services:
app.controller.redis:
class: AppBundle\Controller\RedisController
arguments:
- "@app.util.redis_helper"
services:
app.util.redis_helper:
class: AppBundle\Util\RedisHelper
arguments:
- '%redis.host%'
- '%redis.port%'
namespace AppBundle\Controller;
use AppBundle\Util\RedisHelper;
use RedisException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("/redis", service="app.controller.redis")
*/
class RedisController
{
private $redisHelper;
public function __construct(RedisHelper $redisHelper)
{
$this->redisHelper = $redisHelper;
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/set")
*
* @return Response
*/
public function setAction(Request $request)
{
$key = $request->query->get('key');
$value = $request->query->get('value');
$ttl = $request->query->get('ttl');
$result = null;
try {
if ($key && $value) {
$this->redisHelper->set($key, $value, $ttl);
$result = ['key' => $key, 'value' => $value, 'ttl' => $ttl];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/get")
*
* @return Response
*/
public function getAction(Request $request)
{
$key = $request->query->get('key');
$result = null;
try {
if ($key) {
$result = ['key' => $key, 'value' => $this->redisHelper->get($key)];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/ttl")
*
* @return Response
*/
public function ttlAction(Request $request)
{
$key = $request->query->get('key');
$result = null;
try {
if ($key) {
$result = ['key' => $key, 'ttl' => $this->redisHelper->getTtl($key)];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/persist")
*
* @return Response
*/
public function persistAction(Request $request)
{
$key = $request->query->get('key');
$result = null;
try {
if ($key) {
$result = ['key' => $key, 'persist' => $this->redisHelper->persist($key)];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/expire")
*
* @return Response
*/
public function expireAction(Request $request)
{
$key = $request->query->get('key');
$ttl = $request->query->get('ttl');
$result = null;
try {
if ($key) {
$result = ['key' => $key, 'expire' => $this->redisHelper->expire($key, $ttl)];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/delete")
*
* @return Response
*/
public function deleteAction(Request $request)
{
$key = $request->query->get('key');
$result = null;
try {
if ($key) {
$result = ['key' => $key, 'expire' => $this->redisHelper->delete($key)];
}
} catch (RedisException $e) {
$result = $e->getMessage();
}
return new Response(json_encode($result));
}
}
Yazan dip notları okuyun!
namespace AppBundle\Util;
use Redis;
class RedisHelper
{
const MIN_TTL = 1;
const MAX_TTL = 3600;
/** @var Redis $redis */
private $redis;
private $host;
private $port;
public function __construct($host, $port)
{
$this->host = $host;
$this->port = $port;
}
/**
* Get the value related to the specified key.
*/
public function get($key)
{
$this->connect();
return $this->redis->get($key);
}
/**
* set(): Set persistent key-value pair.
* setex(): Set non-persistent key-value pair.
*/
public function set($key, $value, $ttl = null)
{
$this->connect();
if (is_null($ttl)) {
$this->redis->set($key, $value);
} else {
$this->redis->setex($key, $this->normaliseTtl($ttl), $value);
}
}
/**
* Returns 1 if the timeout was set.
* Returns 0 if key does not exist or the timeout could not be set.
*/
public function expire($key, $ttl = self::MIN_TTL)
{
$this->connect();
return $this->redis->expire($key, $this->normaliseTtl($ttl));
}
/**
* Removes the specified keys. A key is ignored if it does not exist.
* Returns the number of keys that were removed.
*/
public function delete($key)
{
$this->connect();
return $this->redis->del($key);
}
/**
* Returns -2 if the key does not exist.
* Returns -1 if the key exists but has no associated expire. Persistent.
*/
public function getTtl($key)
{
$this->connect();
return $this->redis->ttl($key);
}
/**
* Returns 1 if the timeout was removed.
* Returns 0 if key does not exist or does not have an associated timeout.
*/
public function persist($key)
{
$this->connect();
return $this->redis->persist($key);
}
/**
* The ttl is normalised to be 1 second to 1 hour.
*/
private function normaliseTtl($ttl)
{
$ttl = ceil(abs($ttl));
return ($ttl >= self::MIN_TTL && $ttl <= self::MAX_TTL) ? $ttl : self::MAX_TTL;
}
/**
* Connect only if not connected.
*/
private function connect()
{
if (!$this->redis || $this->redis->ping() != '+PONG') {
$this->redis = new Redis();
$this->redis->connect($this->host, $this->port);
}
}
}