Riding Redis @ask.fm

  • 3,207 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,207
On Slideshare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
21
Comments
0
Likes
7

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. RIDING REDIS @
  • 2. 60M REGISTERED USERS 200M MONTHLY UNIQUE USERS 450M PAGEVIEWS A DAY
  • 3. 600 QUESTIONS / SECOND 20K REQUESTS / SECOND 50K LIKES / MINUTE 250K REGISTRATIONS / DAY
  • 4. ~600 SERVERS ~300 RUBY NODES ~50 JAVA NODES ~35 REDIS NODES ~90 MySQL NODES
  • 5. COMPARISON 13B PAGEVIEWS 200M UNIQUE USERS 32M QUESTIONS ANSWERED 13B PAGEVIEWS* 300M UNIQUE USERS** 76.9M POSTS CREATED* 130B PAGEVIEWS*** N/A UNIQUE USERS 340M TWEETS CREATED*** _________________________________________________ * http://www.tumblr.com/press ** http://yahoo.tumblr.com/post/50902111638/tumblr-yahoo ***http://en.wikipedia.org/wiki/Twitter
  • 6. REDIS
  • 7. Open-source Key-value database In-memory Data-structure server REDIS
  • 8. Salvatore Sanfilippo @antirez REDIS AUTHOR
  • 9. TWITTER INSTAGRAM STACK-OVERFLOW BLIZZARD WHO IS USING REDIS?
  • 10. 6 SCENARIOS 6 REDIS DATA-STRUCTURES
  • 11. COUNTERS STRING MESSAGES QUEUE LIST USER ACTIVITY MATRIX HASH FUNCTIONAL SWITCHES BIT OPERATIONS THE WALL SORTED SET REAL-TIME MONITORING PUB / SUB
  • 12. Scenario 1 : Counters
  • 13. GLOBAL COUNTERS ACTIVE USERS QUESTIONS ASKED TODAY LIKES TOTALLY REGISTRATIONS THIS MONTH
  • 14. SELECT count(*) FROM users WHERE state='active'; NAIVE SOLUTION
  • 15. REDIS STRING MOST BASIC REDIS TYPE BINARY SAFE UP TO 512 Mb OPERATIONS INCR, DECR
  • 16. @redis.incr "users/active/total" ... @redis.decr "users/active/total" users / active / total 61 771 480 users / inactive / total 6 943 366 EXAMPLE
  • 17. USERS COUNTERS
  • 18. @redis.incr "user/#{@user.id}/answers" .. @redis.decr "user/#{@user.id}/likes" .. @redis.incr "user/#{@user.id}/gifts" user / :user_id/ answers 57 user / :user_id / likes 13 905 user / :user_id / gifts 27 EXAMPLE #2: USERS COUNTERS
  • 19. COUNTERS CONSISTENCY
  • 20. CONSISTENCY = 1 / PERFORMANCE
  • 21. @redis.expire "user/#{@user.id}/inbox_questions", 1.day SOLVED MOST CASES FOR US REDIS TTL
  • 22. SCALABILITY
  • 23. @redis_shard_map = { 0 => Redis.new(:host=>"redis_host_0"), 1 => Redis.new(:host=>"redis_host_1"), ..., 7 => Redis.new(:host=>"redis_host_7") } @redis = @redis_shard_map[@user.id % 8] @redis.incr "user/#{@user.id}/answers" SCALABILITY (2)
  • 24. Scenario 2 : Messages Queue
  • 25. THIRD PARTY INTERACTION
  • 26. RUBY BLOCKING MODEL
  • 27. Resque to the rescue https://github.com/resque/resque
  • 28. REDIS-BACKED LIBRARY FOR ● CREATING BACKGROUND JOBS ● PLACING THOSE JOBS ON MULTIPLE QUEUES ● AND PROCESSING THEM LATER RESQUE
  • 29. REDIS LIST SIMPLY LISTS OF STRINGS MAX LENGTH 232 - 1 CONSTANT TIME INSERTION OPERATIONS: LPUSH, LPOP, RPUSH, RPOP LREM, LRANGE
  • 30. WORKFLOW
  • 31. Why Resque?
  • 32. Resque.enqueue(PostToFacebookJob, "Hello world") ADDING A NEW JOB
  • 33. @redis.lpush 'queue:facebook', '{ "class":"PostToFacebookJob", "args":["Hello world"] }' O(1) COMPLEXITY
  • 34. @redis.rpop "queue:facebook" O(1) GETTING A JOB FROM QUEUE
  • 35. Scenario 3 : User activity matrix
  • 36. ROBOTS CRAWLERS SPAM TIME-BASED RESTRICTIONS
  • 37. POST ASK A QUESTION LOGIN LIKE GET PROFILE VIEW USER ACTIONS
  • 38. LIMIT ACTIVITY PER MINUTE PER HOUR PER DAY REQUIREMENTS
  • 39. REDIS HASH MAPS BETWEEN STRING FIELDS AND VALUES MAX PAIRS 232 - 1 OPERATIONS: HGET, HGETALL HSET, HDEL
  • 40. LIKES QUESTIONS REQUESTS user/:uid/date/:today/minute/:minute 12 3 27 user/:uid/date/:today/hour/:hour 34 15 113 user/:uid/date/:today/day/:day 158 22 529 STRUCTURE
  • 41. def register_users_like!(user_id) minute = @redis.hincrby minute_key, 'like', 1 hour = @redis.hincrby hour_key, 'like', 1 day = @redis.hincrby day_key, 'like', 1 end EXAMPLE: REGISTER ACTIVITY
  • 42. def allowed_to_like_questions?(user_id) minute = @redis.hget minute_key, "likes" hour = @redis.hget hour_key, "likes" day = @redis.hget day_key, "likes" return per_minute < LIKES_PER_MINUTE_THRESHOLD && per_hour < LIKES_PER_HOUR_THRESHOLD && per_day < LIKES_PER_DATE_THRESHOLD end EXAMPLE: ALLOWED?
  • 43. @redis.expire per_minute_key, 1.minute @redis.expire per_hour_key, 1.hour @redis.expire per_day_key, 1.day CLEANUP
  • 44. SCALABILITY SCALE BY USER_ID DATE PHASE OF THE MOON
  • 45. CONSISTENT HASHING
  • 46. Scenario 4 : Functional switches
  • 47. TURN ON/OFF ANY FEATURE ON SITE REQUIREMENTS
  • 48. PHOTO ANSWERS VIDEO ANSWERS WALL STREAM DATABASE SHARDS SET POSTS PER PAGE FUNCTIONALITY
  • 49. BIT OPERATIONS BIT OPERATIONS SETBIT, GETBIT BITCOUNT
  • 50. @redis.setbit common_settings_key, WALL_ENABLED, true EXAMPLE
  • 51. MASTER / SLAVE REPLICATION SCALABILITY
  • 52. Scenario 5 : The Wall
  • 53. THE WALL
  • 54. THE WALL
  • 55. SHOW FRIENDS POSTS INITIAL REQUIREMENT
  • 56. SELECT * FROM questions q LEFT JOIN followships f ON (q.user_id = f.friend_id) WHERE f.user_id = :my_user_id ORDER BY q.answered_at LIMIT 0,25 SOLUTION
  • 57. LATER REQUIREMENTS LIKES INTRODUCED SHOW RETWEETS UNIQUENESS OF ANSWERS ORDERED BY FIRST OCCURRENCE PAGINATION NEEDED DO NOT SHOW OWN POSTS SHOW RETWEETS SINCE STARTED FOLLOWING A FRIENDS
  • 58. MORE REQUIREMENTS DO NOT SHOW RETWEETS IF ANSWERER OR RETWEETER IS DISABLED SHOW LATEST FRIENDS WHO LIKED A QUESTION
  • 59. OUR SOLUTION
  • 60. IDEA STORE SEPARATE SET OF QUESTIONS FOR EVERY USER
  • 61. NON REPEATING COLLECTIONS OF STRINGS EACH MEMBER ASSOCIATED WITH SCORE QUICKLY ACCESS ELEMENTS IN ORDER FAST EXISTENCE TEST FAST ACCESS TO ELEMENTS IN THE MIDDLE REDIS SORTED SET
  • 62. user/:user_id/wall score_1 score_2 ... score_N question_id_1 question_id_2 ... question_id_N score - timestamp, when the question_id first occurred in a set STRUCTURE
  • 63. ● GET USERS WALL ○ ZREVRANGEBYSCORE - O(log(N)+M) ● USER ANSWERED A QUESTION ○ ZADD - O(log(N)) ● LIKE ○ ZRANK - O(log(N)) ○ ZADD - O(log(N)) ● REMOVE ANSWER ○ ZREM - O(M*log(N) OPERATIONS
  • 64. GUARANTEED 1000-1500 POSTS ON WALL PERIODICALLY CALL ZCARD ZREMRANGEBYRANK CLEANUP
  • 65. USER_ID SHARDING
  • 66. Scenario 6 : Real time monitoring
  • 67. PATTERN DETECTION REQUIREMENT
  • 68. HUMAN vs MACHINE
  • 69. MySQL TABLE PULL INITIAL SOLUTION
  • 70. PUBLISH / SUBSCRIBE MESSAGING PARADIGM ALLOW PATTERN-MATCHING SUBSCRIPTIONS OPERATIONS: SUBSCRIBE, UNSUBSCRIBE PUBLISH REDIS PUB/SUB
  • 71. SCHEMA
  • 72. MODERATORS PANEL
  • 73. Time complexity: O(N+M) where N is the number of clients subscribed to the receiving channel and M is the total number of subscribed patterns (by any client). SCALING
  • 74. So, why Redis?
  • 75. SIMPLE FAST FLEXIBLE ROBUST FREE WHY REDIS?
  • 76. CLUSTERING WHAT'S MISSING
  • 77. Not covered?
  • 78. SETS LUA SCRIPTING TRANSACTIONS PIPELINED NOT COVERED
  • 79. JAVA
  • 80. Questions