Top Banner
REDIS FOR YOUR BOSS ELENA KOLEVSKA
29

Redis for your boss

Jan 08, 2017

Download

Software

Elena Kolevska
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Redis for your boss

REDIS FOR YOUR BOSSELENA KOLEVSKA

Page 2: Redis for your boss

Who am I ?A nomad earthling. Lead developer @ www.speedtocontact.com

BLOG.ELENAKOLEVSKA.COM@ELENA_KOLEVSKA

Page 3: Redis for your boss

(Really) SHORT INTRONo, seriously!

Page 4: Redis for your boss

REDIS IS AN OPEN SOURCE (BSD licensed), IN-MEMORY DATA STRUCTURE STORE, USED

AS DATABASE, CACHE AND MESSAGE BROKER

The 'Definition' on redis.io

Page 5: Redis for your boss

BASIC FEATURES:▸ Different data structures

▸ Keys with a limited time-to-live▸ Transactions▸ Pipelining▸ Lua scripting▸ Pub/Sub

▸ Built-in replication▸ Different levels of on-disk persistence

Page 6: Redis for your boss
Page 7: Redis for your boss

SPEED

Page 8: Redis for your boss

AVAILABLE CLIENTS IN:ActionScript bash C C# C++ Clojure Common lisp Crystal D Dart Elixir emacs lisp Erlang Fancy gawk GNU Prolog Go Haskell Haxe Io Java Javascript Julia Lua Matlab mruby Nim Node.js Objective-C OCaml Pascal Perl PHP Pure Data Python R Racket Rebol Ruby Rust Scala Scheme Smalltalk Swift Tcl VB VCL

Page 9: Redis for your boss

AVAILABLE DATA STRUCTURES▸ Strings (Binary safe, can be anything from "hello world" to a jpeg file)

▸ Lists (Collections of string elements sorted according to the order of insertion)

▸ Sets (Collections of unique, unsorted string elements)

▸ Sorted sets (It's like Sets with a score)

▸ Hashes (Maps of fields associated to values. Think non-nested json objects)

▸ Bitmaps (Manipulate Strings on a bit level)

▸ HyperLogLogs (Probabilistic data structure used to estimate the cardinality of a set)

Page 10: Redis for your boss

Imagine...

Page 11: Redis for your boss

TWITTER ANALYSIS TOOL▸ Track a selected group of hashtags (#gameofthrones, #got, #gotseason7)

▸ Count mentions of certain keywords ('winter is coming', 'tyrion', 'jon snow', 'stark', 'targaryen', 'cersei', 'asha greyjoy', 'Khaleesi', 'sansa', 'arya')

METRICS:▸ A feed of all tweets containing one of the hashtags

▸ Total number of tweets with one or more of the selected hashtags▸ A leaderboard of keyword frequency▸ A feed of tweets per keyword

Page 12: Redis for your boss

[1] CONNECTING TO REDIS

Page 13: Redis for your boss

[1] CONNECTING TO REDIS

Install the PRedis package using composer composer require predis/predis

... // Initialize the client $parameters = [ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379 ]; $client = new Predis\Client($parameters, ['prefix' => 'twitter_stats:']);

Page 14: Redis for your boss

[2] SET TRACKED DATA

Page 15: Redis for your boss

[2] SET TRACKED DATA

Use sets to store all the hashtags we'll be looking at and all the keywords as well

$client->sadd('hashtags', 'gameofthrones','got', 'gotseason7'); // hashtags | 'gameofthrones' // | 'got' // | 'gotseason7'

$client->sadd('keywords', 'winter is coming', 'winterfell', 'jon snow', 'stark', 'targaryen', 'cersei', 'asha greyjoy', 'dorne', 'Khaleesi' 'hodor', 'sansa', 'arya', 'white walkers', 'the night king');

Page 16: Redis for your boss

[3] GET THE DATA

Page 17: Redis for your boss

[3] GET THE DATA

Use Twitter Stream API to receive notifications for tweets containing any of the hashtags we're following

$hashtags = $client->smembers('hashtags'); // array (size=3) // 0 => string 'got' (length=3) // 1 => string 'gameofthrones' (length=13)

Page 18: Redis for your boss

Save every new tweet from the stream as a separate String. $keyname = 'tweet_id:' . $tweet_id; $tweet_contents = "Winter is coming Khaleesi! #gameofthrones";

$client->set($keyname, $tweet_contents) // 'tweet_id:45645656' | 'Winter is coming Khaleesi! #gameofthrones'

And then push to a queue to be processed asynchronously // Use the list data structure as a queue $client->lpush('message_queue', $keyname); // 'message_queue' | 'tweet_id:45645656' // | 'tweet_id:44645234' // | 'tweet_id:43645232'

Page 19: Redis for your boss

[4] WORKER TO PROCESS THE QUEUED JOBS

Page 20: Redis for your boss

[4] WORKER TO PROCESS THE QUEUED JOBS

A separate worker will be grabbing jobs off the top of the queue and processing them: $message_queue = $client->rpop('message_queue'); // 'message_queue' | 'tweet_id:45645656' // | 'tweet_id:44645234' // | 'tweet_id:43645232'

Reliable queue: RPOPLPUSH, BRPOPLPUSH

Blocking queue: BLPOP, BRPOP

Page 21: Redis for your boss

[5] PROCESS THE TWEET CONTENT

Page 22: Redis for your boss

[5] PROCESS THE TWEET CONTENT

$tweet_contents = $client->get($keyname); $keywords = $client->smembers('keywords');

foreach ($keywords as $keyword) { $tweet_contents = strtolower($tweet_contents); $keyword = strtolower($keyword); if (strpos($tweet_contents,$keyword) !== false){ $client->zincrby('mention_counter', 1, $keyword); // Increase the counter for this specific keyword // mention_counter | 'tyrion' => 9.00 // | 'the wall' => 5.00 // | 'arya' => 4.00 $keyword_feed_keyname = 'keyword_feeds:'. $keyword; $client->lpush($keyword_feed_keyname, $tweet_contents); // Add the tweet to the keyword's feed $client->ltrim($keyword_feed_keyname, 0, 50); } }

$client->incr('total_count'); // Increase the general tweet count

$client->lpush('main_feed', $tweet_contents); $client->ltrim('main_feed', 0, 100);

Page 23: Redis for your boss

[6] SHOW THE STATS

$total_count = $client->get('total_count'); // 'total_count' | 259

$scores = $client->zrevrangebyscore('mention_counter', '+inf', '-inf', ['withscores'=>1]); // mention_counter | 'tyrion' => 9.00 // | 'the wall' => 5.00 // | 'arya' => 4.00

// Feed by keyword foreach ($scores as $keyname => $score) { $keyword_feeds[$keyname] = $client->lrange('keyword_feeds:' . $keyname, 0, -1); }

// Feed of all tweets containing one of the specified hashtags $main_feed = $client->lrange('main_feed', 0, -1);

Page 24: Redis for your boss

[7] USEFUL EXTRAS

Page 25: Redis for your boss

[7] USEFUL EXTRASAPI RATE LIMIER

$ip = $_SERVER['REMOTE_ADDR'] ; $timestamp = time(); //unix timestamp $key = 'api_rate_limits:' . $timestamp . ':' . $ip; // $key = 'api_rate_limits:1473613000:192.168.10.1 '

$api_requests = $client->get($keyname);

if (!is_null($api_requests) && $api_requests >= 3){ throw new Exception('Too many requests per second'); }else{ $client->multi(); $client->incr($key); $client->expire($key,10); $client->exec(); }

Page 26: Redis for your boss

[7] USEFUL EXTRASPIPELINING

$keyname = 'tweet_id:' . $tweet_id; $keywords = $client->smembers('keywords');

$pipe = $client->pipeline(); $pipe->set($keyname, $tweet_contents);

foreach ($keywords as $keyword) { [...] }

$pipe->incr('total_count'); $pipe->lpush('main_feed', $tweet_contents); $pipe->ltrim('main_feed', 0, 20); $replies = $pipe->execute();

Page 27: Redis for your boss

[7] USEFUL EXTRASLUA SCRIPTING

Page 28: Redis for your boss

Thank you!

Page 29: Redis for your boss

Questions?@ELENA_KOLEVSKA

HTTPS://JOIND.IN/TALK/C68B2