Transcript
Page 1: Redis - Your Advanced In-Memory Key-Value Store

Jordi Boggiano@seldaekhttp://nelm.io/

Redis - Your AdvancedIn-Memory Key-Value Store

Page 2: Redis - Your Advanced In-Memory Key-Value Store

About Me

Belgian living in Zürich, Switzerland

Weby stuff for 10 years http://seld.be

Symfony2, Composer and other OSS contributions http://github.com/Seldaek

Working at Nelmio http://nelm.io Symfony2 & frontend performance consulting

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 3: Redis - Your Advanced In-Memory Key-Value Store

Agenda

IntroFeaturesUse CasesUsing it with PHP

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 4: Redis - Your Advanced In-Memory Key-Value Store

Redis

Wut?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 5: Redis - Your Advanced In-Memory Key-Value Store

Store

You put data in it

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 6: Redis - Your Advanced In-Memory Key-Value Store

Key-Value Store

Like NoSQL?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 7: Redis - Your Advanced In-Memory Key-Value Store

In-Memory Key-Value Store

Like Memcached?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 8: Redis - Your Advanced In-Memory Key-Value Store

In-Memory Key-Value Store

Memory is fast, but ephemeral

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 9: Redis - Your Advanced In-Memory Key-Value Store

Persist to Disk

Fast and lasting

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 10: Redis - Your Advanced In-Memory Key-Value Store

Created by @antirez

Sponsored by VMWare

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 11: Redis - Your Advanced In-Memory Key-Value Store

So how does it work?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 12: Redis - Your Advanced In-Memory Key-Value Store

Simple Text Protocol

Human Readable!

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 13: Redis - Your Advanced In-Memory Key-Value Store

Example - Client Library1 SET key value

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 14: Redis - Your Advanced In-Memory Key-Value Store

Example - Client Library1 SET key value2 > OK

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 15: Redis - Your Advanced In-Memory Key-Value Store

Example - Client Library1 SET key value2 > OK3 GET key

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 16: Redis - Your Advanced In-Memory Key-Value Store

Example - Client Library1 SET key value2 > OK3 GET key4 > "value"

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 17: Redis - Your Advanced In-Memory Key-Value Store

Example - Low Level1 *32 $33 SET4 $35 key6 $57 value

1 +OK

1 *22 $33 GET4 $35 key

1 $52 value

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 18: Redis - Your Advanced In-Memory Key-Value Store

Example - Low Level1 *3\r\n2 $3\r\n3 SET\r\n4 $3\r\n5 key\r\n6 $5\r\n7 value\r\n

1 +OK\r\n

1 *2\r\n2 $3\r\n3 GET\r\n4 $3\r\n5 key\r\n

1 $5\r\n2 value\r\n

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 19: Redis - Your Advanced In-Memory Key-Value Store

Data Types

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 20: Redis - Your Advanced In-Memory Key-Value Store

Strings1 SET name Bob2 SET age 203 MGET name age4 > Bob5 > 20

1 GETSET name Alice2 > Bob

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 21: Redis - Your Advanced In-Memory Key-Value Store

Strings1 SETEX age 3 202 GET age3 > 204 // .. 3 seconds later ..5 GET age6 > null

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 22: Redis - Your Advanced In-Memory Key-Value Store

Integers1 INCR count2 > 13 INCR count4 > 25 INCRBY count 36 > 5

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 23: Redis - Your Advanced In-Memory Key-Value Store

Hashes01 HMSET user name Alice email

[email protected] HGET user email03 > [email protected] HKEYS user05 > name06 > email07 HGETALL user08 > name09 > Alice10 > email11 > [email protected]

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 24: Redis - Your Advanced In-Memory Key-Value Store

Lists01 RPUSH admins Alice02 > 103 RPUSH admins Bob04 > 205 LINDEX admins 006 > Alice07 LLEN admins08 > 209 RPOP admins10 > Bob

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 25: Redis - Your Advanced In-Memory Key-Value Store

Sets01 SADD page:3:visitors 13402 > 103 SADD page:3:visitors 25304 > 105 SADD page:3:visitors 25306 > 007 SCARD page:3:visitors08 > 209 SMEMBERS page:3:visitors10 > 13411 > 25312 SISMEMBER page:3:visitors 34913 > 0

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 26: Redis - Your Advanced In-Memory Key-Value Store

Sets1 SADD page:6:visitors 2532 SADD page:6:visitors 9233 SADD page:6:visitors 134 SINTER page:3:visitors page:6:visitors5 > 253

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 27: Redis - Your Advanced In-Memory Key-Value Store

Sorted Sets1 ZADD highscores 2930 Alice2 ZADD highscores 1546 Bob3 ZREVRANGE highscores 0 10 WITHSCORES4 > Alice5 > 29306 > Bob7 > 1546

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 28: Redis - Your Advanced In-Memory Key-Value Store

Sort of Lists? Listed Sets?Lists

Sets

Sorted Sets

1 array('foo', 'bar')

1 shuffle(array('foo', 'bar'))

1 ksort(array(3 => 'foo', 1 => 'bar'))

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 29: Redis - Your Advanced In-Memory Key-Value Store

The basic datatypes of everylanguage exist in Redis

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 30: Redis - Your Advanced In-Memory Key-Value Store

Process data in Redisinstead of PHP

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 31: Redis - Your Advanced In-Memory Key-Value Store

A Few Features

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 32: Redis - Your Advanced In-Memory Key-Value Store

Atomic Operations1 SETNX name Alice2 GET name3 > Alice4 SETNX name Bob5 GET name6 > Alice

1 INCR foo2 GET foo3 > 14 INCRBY foo 35 GET foo6 > 4

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 33: Redis - Your Advanced In-Memory Key-Value Store

EXPIRE / EXPIREAT / PERSIST

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 34: Redis - Your Advanced In-Memory Key-Value Store

Pipelining

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 35: Redis - Your Advanced In-Memory Key-Value Store

SORT - SQL in your NoSQL1 SORT key2 SORT key LIMIT 0 10 DESC3 SORT key ALPHA4 SORT page:6:visitors BY user_*->rank GET

user_* DESC

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 36: Redis - Your Advanced In-Memory Key-Value Store

Append-Only File & Snapshots

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 37: Redis - Your Advanced In-Memory Key-Value Store

Pub/Sub1 SUBSCRIBE foo12 PSUBSCRIBE foo*3 PUBLISH foo0 message

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 38: Redis - Your Advanced In-Memory Key-Value Store

Master/Slave Replication

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 39: Redis - Your Advanced In-Memory Key-Value Store

Transactions: MULTI / EXEC /DISCARD

Optimistic Locking with WATCH

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 40: Redis - Your Advanced In-Memory Key-Value Store

Upcoming Features

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 41: Redis - Your Advanced In-Memory Key-Value Store

Lua Scripting: EVAL / EVALSHA

This is great.

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 42: Redis - Your Advanced In-Memory Key-Value Store

EVAL1 EVAL <body> <num_keys_in_args> [<arg1> <arg2> ... <arg_N>]

1 GET A2 EVAL "return redis.call('get', KEYS[1])" 1 A

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 43: Redis - Your Advanced In-Memory Key-Value Store

EVAL

Example: Atomic Conditional Decrement, Client-Side

This may return -ERR, or will block.

1 WATCH foo2 $val = GET foo3 $newVal = max(0, $val - 1); // decrement if foo > 0 client-side4 MULTI5 SET foo $newVal6 EXEC

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 44: Redis - Your Advanced In-Memory Key-Value Store

EVAL

Example: Atomic Conditional Decrement, Server-Side

This is instant and can not fail.

01 EVAL "local value = tonumber(redis.call('get', KEYS[1]))02 if value == nil03 then04 return {err="Value at key is not integer"}05 end06 if value > tonumber(ARGV[1])07 then08 value = value - 109 redis.call('set', KEYS[1], value)10 end11 return value" 1 foo 0

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 45: Redis - Your Advanced In-Memory Key-Value Store

Redis Cluster

Almost as delayed asDuke Nukem Forever

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 46: Redis - Your Advanced In-Memory Key-Value Store

Speed

Redis is FAST.CPU is unlikely to be the

bottleneck.

What do you do whenyou run out of RAM?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 47: Redis - Your Advanced In-Memory Key-Value Store

Wait for Redis Cluster?

If you can. Cluster looks great.

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 48: Redis - Your Advanced In-Memory Key-Value Store

Use sharding, most clientlibraries can do it.

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 49: Redis - Your Advanced In-Memory Key-Value Store

Use Edis, a protocol compatiblestorage-oriented server.http://inaka.github.com/edis/index.html

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 50: Redis - Your Advanced In-Memory Key-Value Store

Use it without persistence, store to disk/DB

and load hot data in memory.A good example in these slides from Wooga

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 51: Redis - Your Advanced In-Memory Key-Value Store

Ok, great. But..

What is it good for?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 52: Redis - Your Advanced In-Memory Key-Value Store

WEB SCALE

THE CLOUD

NOSQL

ELASTIC

HORIZONTAL SCALING

VERTICAL TOO

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 53: Redis - Your Advanced In-Memory Key-Value Store

WEB SCALE

THE CLOUD

NOSQL

ELASTIC

HORIZONTAL SCALING

VERTICAL TOO

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 54: Redis - Your Advanced In-Memory Key-Value Store

BULLSHIT

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 55: Redis - Your Advanced In-Memory Key-Value Store

Get real"If you do actually have to scale,then your database isn't going to

magically do it for you."

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 56: Redis - Your Advanced In-Memory Key-Value Store

Really.

What is it good for?

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 57: Redis - Your Advanced In-Memory Key-Value Store

Storing Sessions

Caching Data

Other typical Memcached uses

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 58: Redis - Your Advanced In-Memory Key-Value Store

Caching: Newspaper SiteExpensive readsFast-changing pagesDynamic tracking of what's read for users

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 59: Redis - Your Advanced In-Memory Key-Value Store

Caching: Newspaper SiteCache generic results:

Store user read-state in sets

Combine and render for each user

1 SETEX <pageid>:content 600 <data>

1 SADD <pageid>:views <userid>

1 GET <pageid>:content2 SISMEMBER <pageid>:views <userid>

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 60: Redis - Your Advanced In-Memory Key-Value Store

Logging, games and otherwrite-heavy usages

1 LPUSH logs "Log message"2 // keep the last 1000 entries3 LTRIM logs 0 999

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 61: Redis - Your Advanced In-Memory Key-Value Store

Highscore tables

Note: players will only be listed once since it is a set.

1 ZADD scores 4290 <playerid>2 ZADD scores 390 <playerid2>3 // ...4 ZREVRANK scores <playerid> // 05 ZREVRANGE scores 0 10 WITHSCORES

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 62: Redis - Your Advanced In-Memory Key-Value Store

Who's online now?1 ZADD visits <unix> <userid>2 ZADD visits 1327681399 523 ZADD visits 1327683245 184 ZRANGEBYSCORE visits <unix>-3600 <unix>5 ZREMRANGEBYSCORE visits 0 <unix>-3600

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 63: Redis - Your Advanced In-Memory Key-Value Store

Job QueuesWorkers:

Application:

e.g. the Resque lib from GitHub

1 BRPOP queue

1 LPUSH queue "job description"

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 64: Redis - Your Advanced In-Memory Key-Value Store

Behavior Tracking1 SETBIT click:<item>:<date> <userid> 12 GETBIT click:3:2012-01-28 55239

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 65: Redis - Your Advanced In-Memory Key-Value Store

Last but not least, it puts thefun back in Datafunbases

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 66: Redis - Your Advanced In-Memory Key-Value Store

Usage with PHP

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 67: Redis - Your Advanced In-Memory Key-Value Store

Extension: phpredis

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 68: Redis - Your Advanced In-Memory Key-Value Store

Extension: phpredis

Comes with a session handler, sharding, up to date.

http://github.com/nicolasff/phpredis

1 $redis = new Redis();2 $redis->connect('127.0.0.1', 6379);3 $redis->watch('x');4 $val = $redis->get('x');5 $newVal = max(0, $val - 1);6 $result = $redis->multi()7 ->set('x', $newVal)8 ->exec();9 echo $result !== false ? 'Success' : 'Race lost, try again';

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 69: Redis - Your Advanced In-Memory Key-Value Store

Extension: phpiredis

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 70: Redis - Your Advanced In-Memory Key-Value Store

Extension: phpiredis

Basic hiredis bindings, protocol parsing, low level.

http://github.com/seppo0010/phpiredis

1 $redis = phpiredis_connect('127.0.0.1', 6379);2 phpiredis_command($redis, 'WATCH x');3 $val = phpiredis_command($redis, 'GET x');4 $newVal = max(0, $val - 1);5 phpiredis_command($redis, 'MULTI');6 phpiredis_command($redis, 'SET x '.$newVal);7 $result = phpiredis_command($redis, 'EXEC');8 echo $result !== false ? 'Success' : 'Race lost, try again';

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 71: Redis - Your Advanced In-Memory Key-Value Store

Plain PHP: Predis

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 72: Redis - Your Advanced In-Memory Key-Value Store

Plain PHP: Predis

Very complete, sharding, master/slave auto-select,can use phpiredis for parsing.

http://github.com/nrk/predis

http://github.com/snc/SncRedisBundle (Symfony2integration)

01 $redis = new Predis\Client('tcp://10.0.0.1:6379');02 03 $options = array(04 'cas' => true, // enable Check-and-Set05 'watch' => 'x',06 'retry' => 10, // automatic retries07 );08 09 $result = $redis->multiExec($options, function($transaction) {10 $val = $transaction->get('x');11 $newVal = max(0, $val - 1);12 $transaction->multi();13 $transaction->set('x', $newVal);14 });15 16 echo $result !== false ? 'Success' : 'Race lost 10 times, giving up';

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 73: Redis - Your Advanced In-Memory Key-Value Store

It's fast. It's fun. Try it.

try.redis-db.com

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 74: Redis - Your Advanced In-Memory Key-Value Store

Thank you.

Slides: http://slides.seld.be

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 75: Redis - Your Advanced In-Memory Key-Value Store

Find Out MoreRedis.ioTry RedisThe Little Redis BookRedis Cluster Specification

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be

Page 76: Redis - Your Advanced In-Memory Key-Value Store

Questions?

[email protected]

@seldaek

Feedback:

http://joind.in/4764

Jordi Boggiano Company nelm.ioTwitter @seldaek Blog seld.be


Recommended