Redis is a server: all commands involve network or IPC roundtrips. It is meaningless to compare it to embedded data stores such as SQLite, Berkeley DB, etc ... because the cost of most operations is precisely dominated by network/protocol management. redis manual

installation

Access to the Redis port should be denied to everybody but trusted clients in the network, so the servers running Redis should be directly accessible only by the computers implementing the application using Redis.

redis.conf

# secure, just localhost
bind 127.0.0.1
# development all interfaces
bind 0.0.0.0

in production, use ssh tunnell(port 22) or webadmin UI connecting in localhost.

Redis CLI notes

sudo /etc/init.d/redis-server start
redis
-cli ping

dati stringa:

set test test1
get test
keys user:* # le chiavi che rispondono alla regex
del test

dati lista, servono a fare code e stack in cui si lavora spesso sulle estremità

#con lpush il messaggio più recente sarà in testa, con rpush sarà accodato
lpush list a
lpush list b
lrange list 0 2  # i primi 3
lrange list 0 -1 # dal primo, all'ultimo
lrange list -3 -1 # ultimi 3
ltrim list 0 2 # toglie elementi dalla coda, qui la lascia a 3 elementi, ideale per mantenere una lista limitata in grandezza

gli hash sono molto simili a una tabella in memoria

hmset user:1 name mario email test
hmget user:1 name email

ordinamento dei risultati

SORT user:1:followers BY ALPHA
SORT user:1:followers->name BY ALPHA
# concatenare comandi per estrarre valori dal db
redis-cli KEYS user:*:name | xargs redis-cli MGET

sorted sets: viene uilizzato un campo score per tenere ordinato il set

zadd hackers 1940 "Alan Kay"
zadd hackers 1953 "Richard Stallman"
zadd hackers 1965 "Yukihiro Matsumoto"
 
zrange hackers 0 -1

delete multiple keys:

redis-cli keys "ereg_*" | xargs redis-cli del

basic data types and operations

see http://redis.io/commands/

  • String: Similar to Strings in PHP.
  • List: Similar to a single dimensional array in PHP. You can push, pop, shift and unshift, the elements that are placed in order or insertion FIFO (first in, first out).
  • Hash: Maps between string fields and string values. They are the perfect data type to represent objects (e.g.: A User with a number of fields like name, surname, and so forth).
  • Set: Similar to list, except that it has no order and each element may appear only once.
  • Sorted Set: Similar to Redis Sets with a unique feature of values stored in set. The difference is that each member of a Sorted Set is associated with score, used to order the set from the smallest score to the largest.

see also bitmaps, hyperloglogs

List commands:

  • LPUSH: adds an element to the beginning of a list
  • RPUSH: add an element to the end of a list
  • LPOP: removes the first element from a list and returns it
  • RPOP: removes the last element from a list and returns it
  • LLEN: gets the length of a list
  • LRANGE: gets a range of elements from a list

Hash commands:

  • HSET: sets a key-value on the hash
  • HGET: gets a key-value on the hash
  • HGETALL: gets all key-values from the hash
  • HMSET: mass assigns several key-values to a hash
  • HDEL: deletes a key from the object
  • HINCRBY: increments a key-value from the hash with a given value.

Sets Commands:

  • SADD: adds a N number of values to the key
  • SREM: removes N number of values from a key
  • SISMEMBER: if a value exists
  • SMEMBERS: lists of values in the set.

TTL COmmands:

  • EXPIRE: sets an expiration time, in seconds, for the key after which it is deleted
  • EXPIREAT: sets an expiration time using unix timestamps for the key after which it is deleted
  • TTL: gets the remaining time left for a key expiration
  • PERSIST: makes a key last forever by removing the expiration timer from the key.

Predis

git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git
cd phpRedisAdmin
git clone https://github.com/nrk/predis.git vendor

Predis:

require "predis/autoload.php";
Predis\Autoloader::register();

$R = new Predis\Client(array(
    
'scheme' => 'tcp',
    
'host' => 'hostname',
    
'port' => port,
    
'password' => 'password',
    
'persistent' => '1'  // persistent!
));

$R->set("foo""bar");
$R->setex("key""value"$ttl=1000);//expiring data!
$value $R->get("foo");
var_dump($value);

if( 
$R->exists('random') ){
    echo 
$R->get('random');
}

// counters
$R->set("counter"0);
$R->incr("counter"); // 1
$R->incr("counter"); // 2
$R->decr("counter"); // 1
$R->incrby("counter"5);  // 20
$R->decrby("counter"10); // 10


// LIST
$R->rpush("languages""french"); // [french]
$R->rpush("languages""arabic"); // [french, arabic]

$R->lpush("languages""english"); // [english, french, arabic]
$R->lpush("languages""swedish"); // [swedish, english, french, arabic]

$R->lpop("languages"); // [english, french, arabic]
$R->rpop("languages"); // [english, french]

$R->llen("languages"); // 2

$R->lrange("languages"0, -1); // returns all elements
$R->lrange("languages"01); // [english, french]

//----------------------------------------------------------------------------
// hash
$key ';linus torvalds';;
$R->hset($key';age';, 44);
$R->hset($key';country';, ';finland';);
$R->hset($key'occupation''software engineer');
$R->hset($key'reknown''linux kernel');
$R->hset($key'to delete''i will be deleted');

$R->get($key'age'); // 44
$R->get($key'country')); // Finland

$R->del($key'to delete');

$R->hincrby($key'age'20); // 64

$R->hmset($key, [
    
'age' => 44,
    
'country' => 'finland',
    
'occupation' => 'software engineer',
    
'reknown' => 'linux kernel',
]);

// finally
$data $R->hgetall($key);
print_r($data);


//------------------------------------------------------------------------------
// sets
$key "countries";
$R->sadd($key';china';);
$R->sadd($key, ['england''france''germany']);
$R->sadd($key'china'); // this entry is ignored

$R->srem($key, ['england''china']);

$R->sismember($key'england'); // false

$R->smembers($key); // ['france', 'germany']


//------------------------------------------------------------------------------
// expiration example
$key "expire in 1 hour";
$R->expire($key3600); // expires in 1 hour
$R->expireat($keytime() + 3600); // expires in 1 hour

sleep(600); // don't try this, just an illustration for time spent

$R->ttl($key); // 3000, ergo expires in 50 minutes

$R->persist($key); // this will never expire.

native client ext

pecl install redis
 
# Now get Redis from http://pecl.php.net/package/redis and make a package
cd php-redis-2.2.3/
debuild
dpkg -c ../php5-redis_2.2.3-1_amd64.deb
sudo dpkg -i ../php5-redis_2.2.3-1_amd64.deb

test code connection

<?php
$R 
= new Redis() or die("Cannot load Redis module.");
$R->connect('localhost');
$R->set('random'rand(5000,6000));

use cases

  • Show latest items listings in your home page. This is a live in-memory cache and is very fast. LPUSH is used to insert a content ID at the head of the list stored at a key. LTRIM is used to limit the number of items in the list to 5000. If the user needs to page beyond this cache only then are they sent to the database.
  • Deletion and filtering. If a cached article is deleted it can be removed from the cache using LREM.
  • Leaderboards and related problems. A leader board is a set sorted by score. The ZADD commands implements this directly and the ZREVRANGE command can be used to get the top 100 users by score and ZRANK can be used to get a users rank. Very direct and easy.
  • Order by user votes and time. This is a leaderboard like Reddit where the score is formula the changes over time. LPUSH + LTRIM are used to add an article to a list. A background task polls the list and recomputes the order of the list and ZADD is used to populate the list in the new order. This list can be retrieved very fast by even a heavily loaded site. This should be easier, the need for the polling code isn't elegant.
  • Implement expires on items. To keep a sorted list by time then use unix time as the key. The difficult task of expiring items is implemented by indexing current_time+time_to_live. Another background worker is used to make queries using ZRANGE ... with SCORES and delete timed out entries.
  • Counting stuff. Keeping stats of all kinds is common, say you want to know when to block an IP addresss. The INCRBY command makes it easy to atomically keep counters; GETSET to atomically clear the counter; the expire attribute can be used to tell when an key should be deleted.
  • Unique N items in a given amount of time. This is the unique visitors problem and can be solved using SADD for each pageview. SADD won't add a member to a set if it already exists.
  • Real time analysis of what is happening, for stats, anti spam, or whatever. Using Redis primitives it's much simpler to implement a spam filtering system or other real-time tracking system.
  • Pub/Sub. Keeping a map of who is interested in updates to what data is a common task in systems. Redis has a pub/sub feature to make this easy using commands like SUBSCRIBE, UNSUBSCRIBE, and PUBLISH.
  • Queues. Queues are everywhere in programming. In addition to the push and pop type commands, Redis has blocking queue commands so a program can wait on work being added to the queue by another program. You can also do interesting things implement a rotating queue of RSS feeds to update.
  • Caching. Redis can be used in the same manner as memcache.

queue

queuing system in a distributed platform. You can implement such a queue using the LPUSH and BRPOP commands. With LPUSH you add elements to the start of the list, while the BRPOP removes elements from the list, blocking when no elements are available. But if you want that queue to be reliable, you can consider using the BRPOPLPUSH command, that can add the returned element to an ‘in progress' queue before returning it to the client. This way you can remove the element from the ‘in progress' queue when you successfully handled them, or put them back on the original queue if you failed.

cache

be used in the same manner as memcache.

session storage

pub/sub

Pub/Sub. Keeping a map of who is interested in updates to what data is a common task in systems. Redis has a pub/sub feature to make this easy using commands like SUBSCRIBE, UNSUBSCRIBE, and PUBLISH.

job queue

PHP-Resque: Workers and Queueing

  • Workers can be distributed between multiple machines
  • Includes support for priorities (queues)
  • Resilient to memory leaks (forking)