Your SlideShare is downloading. ×
0
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Redis for the Everyday Developer
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Redis for the Everyday Developer

9,221

Published on

As presented at Confoo 2013. …

As presented at Confoo 2013.

More than some arcane NoSQL tool, Redis is a simple but powerful swiss army knife you can begin using today.

This talk introduces the audience to Redis and focuses on using it to cleanly solve common problems. Along the way, we'll see how Redis can be used as an alternative to several common PHP tools.

4 Comments
34 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,221
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
204
Comments
4
Likes
34
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Redis For TheEveryday Developer Ross Tuck Confoo March 1st, 2013
  • 2. Who Am I?
  • 3. Ross Tuck
  • 4. Team Lead at IbuildingsCodemonkeyHTTP nutHat guy
  • 5. @rosstuck
  • 6. Boring.
  • 7. NoSQL
  • 8. NoNoSQL
  • 9. Evaluation
  • 10. • Created by Salvatore Sanfilippo ( @antirez )• Sponsored by VMware• 4 years old• redis.io
  • 11. “Redis is an open source, advanced key-value store.”
  • 12. “It is often referred to asa data structure server...”
  • 13. Defancypants
  • 14. RedisServer A Server B
  • 15. In-Memory
  • 16. In-Memory
  • 17. The Cool Stuff
  • 18. Fast.
  • 19. Demo.
  • 20. Oh wait, its already done.
  • 21. 120,000~ ops per sec
  • 22. Flexible.
  • 23. (optionally)Persistent.
  • 24. Replication Pub/Sub Transactions Scripting Slices DicesMakes julienne fries
  • 25. “Well, Ross, that sounds cool...”
  • 26. +MySQL Redis
  • 27. MySQL +Redis 4ever
  • 28. Setup
  • 29. apt-get install redis-server Easy but old
  • 30. http://redis.io/download
  • 31. PHP Libraries• 5.3+: Predis• 5.2: Predis or Rediska• C Extension: phpredis• redis-cli
  • 32. $client = new PredisClient();
  • 33. The Surprise Ending
  • 34. PHP MySQLMemcache
  • 35. PHP MySQLMemcache
  • 36. PHPMySQLRedis
  • 37. Its about 80% cases.
  • 38. Use Case #1: Caching
  • 39. Redis has commands.
  • 40. Commands have parameters.
  • 41. Think functions.
  • 42. $client->commandGoesHere($params, $go, $here);
  • 43. SET
  • 44. $client->set(ross:mood, nervous);// Later$client->get(ross:mood); // returns “nervous”
  • 45. $client->set(ross:mood, nervous);$client->expire(ross:mood, 5);// 4 seconds later...$client->get(ross:mood); // “nervous”// 5 seconds later...$client->get(ross:mood); // null
  • 46. $client->set(ross:mood, nervous);$client->expire(ross:mood, 5);
  • 47. $client->setex(ross:mood, 5, nervous);
  • 48. Great for caching
  • 49. Ideal for sessions
  • 50. Use Case #2: Simple Data
  • 51. Search... omg cheezburgers in the lunchroom today. Better hurry if u want 1!!! ^_^How do I store this?
  • 52. key value
  • 53. key valuehomepage_message omg cheezburgers...
  • 54. key valuehomepage_message omg cheezburgers...tps_reports new cover pages on...
  • 55. You already know it.
  • 56. $client->set(home:message, cheezburgers...);$client->get(home:message);
  • 57. Equal EasierMore Fun
  • 58. Use Case #3: Hit Counters
  • 59. increment
  • 60. $client->incr(page:42:views); // 1$client->incr(page:42:views); // 2$client->incr(page:42:views); // 3
  • 61. Redis is hard ;)
  • 62. How is this better?
  • 63. Fast?
  • 64. redis-benchmark====== INCR ====== 10000 requests completed in 0.08 seconds 50 parallel clients 3 bytes payload keep alive: 1100.00% <= 0 milliseconds119047.62 requests per second
  • 65. Fast enough.
  • 66. $client->incr(cookies:eaten);$client->incrBy(cookies:eaten, 2);$client->incrByFloat(cookies:eaten, 0.5); version 2.6+
  • 67. Use Case #4: Latest News
  • 68. “It is often referred to asa data structure server...”
  • 69. “...since keys can contain strings, hashes, lists, sets and sorted sets.”
  • 70. $redis = array();
  • 71. GenericHashListSetSorted Set
  • 72. GenericHash // strings and numbersList $redis[ross:mood] = "happy";Set $redis[foo] = 9;Sorted Set
  • 73. GenericHash // associative arrayList $redis[foo][name] = Bob; $redis[foo][age] = 31;SetSorted Set Objects, forms, records
  • 74. GenericHash // not associativeList $redis[foo][] = zip;Set $redis[foo][] = zap;Sorted Set Lists, stacks, queues
  • 75. Generic // No dupes, no orderHash shuffle(List array_unique($redis[foo])Set );Sorted Set Relations, stats, matching
  • 76. GenericHash // Ordered by *score*List array_unique($redis[foo]);SetSorted Set Curing cancer, world peace Sets but with order or scores
  • 77. Y U NO STOPLISTING THINGS
  • 78. GenericHashListSetSorted Set
  • 79. GenericHashListSetSorted Set
  • 80. // Code$client->lpush(news:latest, Aliens Attack!);// Redis[Aliens Attack!]
  • 81. // 2 hours later...$client->lpush(news:latest, Takei 2016);// Redis[Takei 2016, Aliens Attack!]
  • 82. // That evening...$client->lpush(news:latest, Eggs = Cancer!);// Redis[Eggs = Cancer!, Takei 2016, Aliens Attack!]
  • 83. Recap
  • 84. // Code$client->lpush(news:latest, Aliens Attack!);$client->lpush(news:latest, Takei 2016);$client->lpush(news:latest, Eggs = Cancer!);// Redis[Eggs = Cancer!, Takei 2016, Aliens Attack!]
  • 85. Getting it back out?
  • 86. Start Index$client->lrange(news:latest, 0, 1); En d Index
  • 87. var_dump($client->lrange(news:latest, 0, 1));array(2) { [0]=> string(14) "Eggs = Cancer!" [1]=> string(10) "Takei 2016"}
  • 88. Thats it. Really.
  • 89. What about size?
  • 90. $client->lpush(news:latest, Free Jetpacks!);$client->lpush(news:latest, Elvis Found!);$client->lpush(news:latest, Takei Wins!);//...and so on...
  • 91. ltrim
  • 92. $client->ltrim(news:latest, 0, 2);// Only the three latest stories remain!
  • 93. Cron
  • 94. or simpler...
  • 95. $client->lpush(news:latest, Cats Leave Euro);$client->ltrim(news:latest, 0, 2);
  • 96. Great option for notifications
  • 97. Use Case #5: Tricksy Caching
  • 98. SELECT * FROM ArticlesINNER JOIN Authors ON (complicated joins)-- More joinsWHERE (complicated logic)LIMIT 0, 20
  • 99. SELECT Articles.id FROM ArticlesINNER JOIN Authors ON (complicated joins)-- More joinsWHERE (complicated logic)
  • 100. $client->lpush(search:a17f3, $ids);
  • 101. $client->lrange(search:a17f3, $limit, $offset);
  • 102. SELECT * FROM ArticlesINNER JOIN Authors ON (complicated joins)-- More joinsWHERE Articles.id IN (1, 2, 3)
  • 103. Use Case #6: Recently Viewed
  • 104. GenericHashListSetSorted Set
  • 105. GenericHashList No duplicatesSetSorted Set
  • 106. GenericHashListSet Needs to be orderedSorted Set
  • 107. GenericHashListSetSorted Set Just Right
  • 108. zadd
  • 109. $client->zadd(mykey, 1, mydata); Any integer t or floa
  • 110. $client->zadd(recent, 1, /p/first);
  • 111. $client->zadd(recent, time(), /p/first);
  • 112. $client->zadd(recent, 1338020901, /p/first);$client->zadd(recent, 1338020902, /p/second);$client->zadd(recent, 1338020903, /p/third);$client->zadd(recent, 1338020904, /p/fourth);
  • 113. Reading it back out?
  • 114. $client->zrange(recent, 0, 2);array(3) { [0]=> string(8) "/p/first" [1]=> string(9) "/p/second" [2]=> string(8) "/p/third"}
  • 115. Reverse$client->zrevrange(recent, 0, 2);array(3) { [0]=> string(9) "/p/fourth" [1]=> string(8) "/p/third" [2]=> string(9) "/p/second"}
  • 116. Duplicates?
  • 117. $client->zadd(recent, 1338020901, /p/first);// later...$client->zadd(recent, 1338020928, /p/first);
  • 118. $client->zrevrange(recent, 0, 2);array(3) { [0]=> string(8) "/p/first" [1]=> string(9) "/p/fourth" [2]=> string(8) "/p/third"}
  • 119. Cool.
  • 120. Other things we can do?
  • 121. $client->zrangebyscore(recent, $low, $high);
  • 122. $yesterday = time()-(60*60*24);$client->zrangebyscore(recent, $yesterday, +inf);
  • 123. Intersections
  • 124. zinterstore
  • 125. $client->zinterstore(omg, 2, recent, favorite);$client->zrange(omg, 0, 4);
  • 126. Deletion
  • 127. zrem
  • 128. zremrangebyscore
  • 129. $yesterday = time()-(60*60*24);$client->zremrangebyscore( recent, -inf, $yesterday);
  • 130. We can do a lot.
  • 131. Scores can be anything.
  • 132. Use Case #7: Sharing Data
  • 133. PHP RedisNode.js Python
  • 134. • ActionScript • Java• C • Lua• C# • Node.js• C++ • Objective-C• Clojure • Perl• Common Lisp • PHP• Erlang • Pure Data• Fancy • Python• Go • Ruby• Haskell • Scala• haXe • Smalltalk• Io • Tcl
  • 135. $client = new PredisClient();$client->set(foo, bar);
  • 136. var redis = require("redis");var client = redis.createClient();client.get("foo", redis.print);
  • 137. Step Further...
  • 138. Pub/Sub
  • 139. $client->publish(bids:42, $13.01);
  • 140. client.on("message", function (channel, message) { console.log(channel + "= " + message);});client.subscribe("bids:42");// prints “bids:42= $13.01”
  • 141. yetNot everyday
  • 142. Use Case #8: Worker Queues
  • 143. $client->lpush(jobs:pending, clear_cache);
  • 144. $client->lpush(jobs:pending, {"do":"email", …});
  • 145. $client->lpush(jobs:pending, job:45);
  • 146. // worker$client = new PredisClient(array( read_write_timeout => -1));do { $job = $client->brpop(jobs:pending, 0); doJob($job);} while(true);
  • 147. This will work.
  • 148. However...
  • 149. Things break.
  • 150. Things break.
  • 151. Clients break.
  • 152. Clients break.
  • 153. Clients crash.
  • 154. do { $job = $client->brpop(jobs:pending, 0); doJob($job);} while(true);
  • 155. Multiple keys is the redis way.
  • 156. jobs:pendingjobs:working
  • 157. What we need is: blocking rpop lpush
  • 158. brpoplpush . No, really
  • 159. do { $job = $client->brpoplpush( jobs:pending, jobs:working, 0 ); doJob($job);} while(true);
  • 160. do { $job = $client->brpoplpush( jobs:pending, jobs:working, 0 ); if(doJob($job)) { $client->lrem(jobs:working, 0, $job); }} while(true);
  • 161. Use Case #9: Scripted Commands
  • 162. Use Case #9: Impressing People
  • 163. $client->set(jesse, dude);$client->set(chester, sweet);
  • 164. Lua
  • 165. var argumentslocal first = redis.call(get, KEYS[1]);local second = redis.call(get, KEYS[2]);redis.call(set, KEYS[1], second);redis.call(set, KEYS[2], first);return {first, second};
  • 166. // jesse: dude// chester: sweetEVAL local first... 2 jesse chester// jesse: sweet// chester: dude
  • 167. Eval != Evil *Offer only applies in Redis-Land. . Void where pedantic
  • 168. Dont over do it.
  • 169. Reusing scripts?
  • 170. SCRIPT LOAD local first...// 591d1b681192f606d8cb658e1e173e771a90e60e
  • 171. EVAL local first... 2 jesse chester
  • 172. EVALSHA 591d1... 2 jesse chester
  • 173. Sweet.
  • 174. Epilogue
  • 175. Simple = Powerful
  • 176. Fun.
  • 177. Keep it in RAM.
  • 178. Extensible + Ecosystem
  • 179. Great docs.Use them.
  • 180. Bad for the DB?Might be good for Redis.
  • 181. Bad for the DB?Might be good for Redis.
  • 182. IAEA Kotaku@svdgraaf Alltheragefaces QuickMeme
  • 183. http://joind.in/7971

×