33
Follow this topic: @rjsmelo Redis & ZeroMQ: How to scale your application RICARDO MELO Presented at #PHPLX – 11 July 2013

Redis & ZeroMQ: How to scale your application

  • Upload
    rjsmelo

  • View
    13.027

  • Download
    0

Embed Size (px)

DESCRIPTION

Presented at #PHPLX 11 July 2013 When you need to do some heavy processing how do you scale you application? You can use Redis and ZeroMQ to leverage the heavy work for you! With this presentation we will know more about this two technologies and how they can be used to help solve problems with the performance and scalability of your application.

Citation preview

Page 1: Redis & ZeroMQ: How to scale your application

Follow this topic:

@rjsmelo

Redis & ZeroMQ: How to scale your application

RICARDO MELO

Presented at #PHPLX – 11 July 2013

Page 2: Redis & ZeroMQ: How to scale your application

@rjsmelo 2

RICARDO MELO

● CTO @ DRI● PHP, Mysql, Linux and lots of other OSS

● ZCE, RHCE, LPI 3, ITIL, etc● +10 years building (and breaking) things

Page 3: Redis & ZeroMQ: How to scale your application

@rjsmelo 3

About

● 14 Year old academic spin-off● Pragmatic OSS Orientation● PHP, Mysql, SugarCRM, Drupal, JavaScript, Linux, etc.

● Crafters, Integrators

● Always looking for software developers– Yes, right now!

Page 4: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 4

Outline

● Redis● ZeroMQ● Use Cases● Conclusions

Page 5: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 5

Redis

“Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.”

source: http://redis.io

Page 6: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 6

Predis

● Pure PHP Redis Client– https://github.com/nrk/predis

● Use composer:– composer install

{ "name": "rjsmelo/talk-redis-zmq", "description": "Sample code for Redis & ZeroMQ presentation", "require": { "ext-zmq": "*", "predis/predis": "dev-master" }, "license": "Apache-2.0", "authors": [ { "name": "Ricardo Melo", "email": "[email protected]" } ]}

Page 7: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 7

Strings

1 <?php 2 //redis_strings.php 3 require_once __DIR__ . '/../vendor/autoload.php'; 4 $redis = new Predis\Client('tcp://localhost:6379'); 5 6 // Using SET 7 $redis->set("SampleKey", "Throw me any thing here...."); 8 echo $redis->get("SampleKey") . "\n"; // Throw me any thing here.... 9 10 // Remove Key11 $redis->del("SampleKey");12 13 // Using APPEND14 $redis->append("SampleKey", "Hello"); // Hello15 $redis->append("SampleKey", " World!"); // Hello World!16 echo $redis->get("SampleKey") . "\n";17 18 // Other commands: incr, decr, incrby, getrange, setrange19 // http://redis.io/commands/#string

Page 8: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 8

Lists

1 <?php 2 //redis_lists.php 3 require_once __DIR__ . '/../vendor/autoload.php'; 4 $redis = new Predis\Client('tcp://localhost:6379'); 5 6 $redis->del('SampleList'); 7 8 // Using {L,R}PUSH 9 $redis->lpush('SampleList', 'a'); // a10 $redis->lpush('SampleList', 'b'); // b, a11 $redis->rpush('SampleList', 'c'); // b, a, c12 13 // Using LLEN14 echo $redis->llen('SampleList') . "\n"; // 315 16 // Using LINDEX (note: zero indexed)17 echo $redis->lindex('SampleList', 1) . "\n"; // a18 19 // Using {L,R}POP20 21 echo $redis->lpop('SampleList') . "\n"; // b22 echo $redis->rpop('SampleList') . "\n"; // c23 24 // Other commands: lrange, rpoplpush25 // http://redis.io/commands#list

Page 9: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 9

Sets

1 <?php 2 //redis_sets.php 3 require_once __DIR__ . '/../vendor/autoload.php'; 4 $redis = new Predis\Client('tcp://localhost:6379'); 5 6 $redis->del('SampleSet'); 7 $redis->del('OtherSampleSet'); 8 9 // Using SADD10 $redis->sadd('SampleSet', 'Hello'); // Hello11 $redis->sadd('SampleSet', 'World'); // Hello, World12 $redis->sadd('SampleSet', 'World'); // Hello, World13 14 // Using SMEMBERS15 var_dump($redis->smembers('SampleSet')); // Hello, World16 17 // Using SINTER18 $redis->sadd('OtherSampleSet', 'Hello');19 $redis->sadd('OtherSampleSet', 'All');20 var_dump($redis->sinter('SampleSet', 'OtherSampleSet')); // Hello21 22 // Using SUNION23 var_dump($redis->sunion('SampleSet', 'OtherSampleSet')); // Hello, World, All24 25 // Other commands: smove, srandmember, srem, scard26 // http://redis.io/commands#set

Page 10: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 10

Hashes

1 <?php 2 //redis_hashes.php 3 require_once __DIR__ . '/../vendor/autoload.php'; 4 $redis = new Predis\Client('tcp://localhost:6379'); 5 6 $redis->del('SampleHash'); 7 8 // Using HMSET 9 $redis->hmset("SampleHash", array(10 'prop_a' => 'aaa',11 'prop_b' => 'bbb',12 ));13 14 // Using HGETALL15 var_dump($redis->hgetall("SampleHash")); // prop_a=>aaa, prop_b=>bbb16 17 // Using HSET18 $redis->hset('SampleHash', 'prop_b', 'ccc');19 20 //USING HGET21 echo $redis->hget("SampleHash", 'prop_b') ."\n"; // ccc22 23 // Other commands: hexists, hdel, hlen, hkeys, hvals24 // http://redis.io/commands/#hash

Page 11: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 11

Sorted Sets

1 <?php 2 //redis_sorted_sets.php 3 require_once __DIR__ . '/../vendor/autoload.php'; 4 $redis = new Predis\Client('tcp://localhost:6379'); 5 6 $redis->del('SampleSortedSet'); 7 8 // Using SADD 9 $redis->zadd('SampleSortedSet', 1, 'Hello'); // Hello(1)10 $redis->zadd('SampleSortedSet', 2, 'World'); // Hello(1), World(2)11 $redis->zadd('SampleSortedSet', 3, 'World'); // Hello(1), World(3)12 13 // Using ZRANGE14 var_dump($redis->zrange('SampleSortedSet', 0, -1, array('withscores'=>true))); // Hello(1), World(3)15 16 // Using ZSCORE17 echo $redis->zscore('SampleSortedSet', 'World') . "\n"; // 318 19 // Other commands: zrank, zrevrange, zrangebyscore, zremrangebyscore20 // http://redis.io/commands#sorted_set

Page 12: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 12

ZeroMQ

“ØMQ is a high-performance asynchronous messaging library aimed at use in scalable distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ØMQ system can run without a dedicated message broker. With bindings for 30+ languages”

source: https://en.wikipedia.org/wiki/%C3%98MQ

Page 13: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 13

PHP Module - zmq

## ZMQ instalation - http://www.zeromq.org/intro:get-the-software#

tar xzvf zeromq-3.2.2.tar.gzcd zeromq-3.2.2./configuremakemake installecho "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.confldconfig

## ZMQ PHP Binding Instalation#

pear channel-discover pear.zero.mqpecl install pear.zero.mq/zmq-betaecho "extension=zmq.so" > /etc/php.d/zmq.ini

Page 14: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 14

Socket Types

● Threads in a process (inproc://)● Processes in a box (ipc://)● Processes over the network (tcp://)● Multicast group (pgm://)

Page 15: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 15

Pattern: Request - Reply

Page 16: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 16

Pattern: Request - Reply

1 <?php 2 // zmq_request.php 3 $context = new ZMQContext(); 4 5 $requester = new ZMQSocket($context, ZMQ::SOCKET_REQ); 6 $requester->connect("tcp://localhost:5555"); 7 8 for ($number = 0 ; $number <= 10 ; $number++) { 9 $mensage = "Hello " . $number . "!";10 echo "Sending - " . $mensage . "\n";11 $requester->send($mensage);12 $reply = $requester->recv();13 echo "Received - " . $reply . "\n";14 }

1 <?php 2 //zmq_reply.php 3 $context = new ZMQContext(); 4 5 $responder = new ZMQSocket($context, ZMQ::SOCKET_REP); 6 $responder->bind("tcp://*:5555"); 7 8 while (true) { 9 $request = $responder->recv();10 echo $request . "\n";11 sleep (1); // some work12 $responder->send("Reply to: " . $request);13 }

Page 17: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 17

Pattern: Publish - Subscribe

Page 18: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 18

Pattern: Publish - Subscribe 1 <?php 2 // zmq_publisher.php 3 $context = new ZMQContext(); 4 5 $publisher = $context->getSocket(ZMQ::SOCKET_PUB); 6 $publisher->bind("tcp://*:5556"); 7 8 $timezones = array('UTC', 'EST'); 9 while (true) {10 foreach($timezones as $tz) {11 date_default_timezone_set($tz);12 $message = date('T:c'); // the message to broadcast13 $publisher->send($message);14 }15 sleep(1);16 } 1 <?php

2 // zmq_subscriber.php 3 $context = new ZMQContext(); 4 5 $subscriber = $context->getSocket(ZMQ::SOCKET_SUB); 6 $subscriber->connect("tcp://localhost:5556"); 7 8 $filter = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : "UTC"; 9 $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter);10 11 while (true) {12 $message = $subscriber->recv();13 echo substr($message,4) . "\n"; // remove prefix14 }

Page 19: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 19

Pattern: Pipeline

Page 20: Redis & ZeroMQ: How to scale your application

20

Pattern: Pipeline 1 <?php 2 // zmq_ventilator.php 3 // extracted from: http://zguide.zeromq.org/ 4 5 $context = new ZMQContext(); 6 7 // Socket to send messages on 8 $sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH); 9 $sender->bind("tcp://*:5557");10 11 echo "Press Enter when the workers are ready: ";12 $fp = fopen('php://stdin', 'r');13 $line = fgets($fp, 512);14 fclose($fp);15 echo "Sending tasks to workersâÀ¦", PHP_EOL;16 17 // The first message is "0" and signals start of batch18 $sender->send(0);19 20 // Send 100 tasks21 $total_msec = 0; // Total expected cost in msecs22 for ($task_nbr = 0; $task_nbr < 100; $task_nbr++) {23 // Random workload from 1 to 100msecs24 $workload = mt_rand(1, 100);25 $total_msec += $workload;26 $sender->send($workload);27 28 }29 30 printf ("Total expected cost: %d msec\n", $total_msec);31 sleep (1); // Give 0MQ time to deliver

Page 21: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 21

Pattern: Pipeline

1 <?php 2 // zmq_worker.php 3 // extracted from: http://zguide.zeromq.org/ 4 5 $context = new ZMQContext(); 6 7 // Socket to receive messages on 8 $receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); 9 $receiver->connect("tcp://localhost:5557");10 11 // Socket to send messages to12 $sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH);13 $sender->connect("tcp://localhost:5558");14 15 // Process tasks forever16 while (true) {17 $string = $receiver->recv();18 19 // Simple progress indicator for the viewer20 echo $string, PHP_EOL;21 22 // Do the work23 usleep($string * 1000);24 25 // Send results to sink26 $sender->send("");27 }

Page 22: Redis & ZeroMQ: How to scale your application

22

Pattern: Pipeline 1 <?php 2 // zmq_sink.php 3 // extracted from: http://zguide.zeromq.org/ 4 5 // Prepare our context and socket 6 $context = new ZMQContext(); 7 $receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); 8 $receiver->bind("tcp://*:5558"); 9 10 // Wait for start of batch11 $string = $receiver->recv();12 13 // Start our clock now14 $tstart = microtime(true);15 16 // Process 100 confirmations17 $total_msec = 0; // Total calculated cost in msecs18 for ($task_nbr = 0; $task_nbr < 100; $task_nbr++) {19 $string = $receiver->recv();20 if ($task_nbr % 10 == 0) {21 echo ":";22 } else {23 echo ".";24 }25 }26 27 $tend = microtime(true);28 29 $total_msec = ($tend - $tstart) * 1000;30 echo PHP_EOL;31 printf ("Total elapsed time: %d msec", $total_msec);32 echo PHP_EOL;

Page 23: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 23

Pattern: Pipeline

Page 24: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 24

Use Case: Service Cluster

Reference: http://zguide.zeromq.org/page:all#Service-Oriented-Reliable-Queuing-Majordomo-Pattern

Page 25: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 25

Use Case: “Unix Style” Application

● Lots of simple, “focused” programs– Or in different servers, different languages, etc

● All components collaborate to get the job done– cat file | sort | uniq -c

● Glue everything with ZeroMQ

Page 26: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 26

Use Case: Cache

● We need to cache some values for speed

● Use SET / GET on Redis● I could use memcache, but this is a Redis Talk :-)

● They have similar performance– http://redis.io/topics/benchmarks

Page 27: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 27

Use Case: Buffer

● Use Redis as a FIFO (or LIFO)● Hidden Goods

– Decoupling

– Flow control

– rpoplpush

Page 28: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 28

Use Case: Background Tasks

● Your application needs to do some heavy work– Send Email

– Image Resizing

– Mega Huge map-reduce query to your pentabyte cluster :-)

● You don't want to keep your user waiting

● Send things to background

Page 29: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 29

Use Case: Background Tasks

● Use Redis as your Job Queue– Your application should send job to be run and parameters to the

queue

● Use workers to POP jobs from the queue and do the heavy work.

● Don't reinvent the well– Look for php-resqueue

Page 30: Redis & ZeroMQ: How to scale your application

1999 - 2013 DRI. Some Rights Reserved. 30

Conclusions

● Both ZeroMQ and Redis are extremely fast

● ZeroMQ is great to “glue things” as well as adding flexibility to scale dynamical

● Redis is great as a queue and allows you to cope with your load.

Page 31: Redis & ZeroMQ: How to scale your application

Thank you

Page 32: Redis & ZeroMQ: How to scale your application

Follow this topic:

@rjsmelo

QA

Code: https://github.com/rjsmelo/talk-redis-zmq

Feedback: https://joind.in/talk/view/8937

Page 33: Redis & ZeroMQ: How to scale your application

www.dri-global.com

@rjsmelo

[email protected]