SlideShare a Scribd company logo
1 of 57
Redis in Practice
NoSQL NYC • December 2nd, 2010
    Noah Davis & Luke Melia
About Noah & Luke

Weplay.com
Rubyists
Running Redis in production since mid-2009
@noahd1 and @lukemelia on Twitter
Pronouncing Redis
Tonight’s gameplan
Fly-by intro to Redis
Redis in Practice
   View counts                     Q&A
                           throughout, please.
   Global locks               We love being
   Presence                    interrupted.

   Social activity feeds
   Friend suggestions
   Caching
Salvatore
     Sanfilippo
 Original author of Redis.
   @antirez on Twitter.
       Lives in Italy.
Recently hired by VMWare.
  Great project leader.
Describing Redis

Remote dictionary server
“advanced, fast, persistent key- value database”
“Data structures server”
“memcached on steroids”
In Salvatore’s words

 “I see Redis definitely more as a flexible tool
than as a solution specialized to solve a specific
  problem: his mixed soul of cache, store, and
    messaging server shows this very well.”
             - Salvatore Sanfilippo
Qualities
Written in C
Few dependencies
Fast
Single-threaded
Lots of clients available
Initial release was March 2009
Features
Key-value store where a value is one of:
   scalar/string, list, set, sorted sets, hash
Persistence: in-memory, snapshots, append-only log, VM
Replication: master-slave, configureable
Pub-Sub
Expiry
“Transaction”-y
In development: Redis Cluster
What Redis ain’t (...yet)

Big data
Seamless scaling
Ad-hoc query tool
The only data store you’ll ever need
Who’s using Redis?
VMWare
                 Grooveshark
Github
                 Superfeedr
Craigslist
                 Ravelry
EngineYard
                 mediaFAIL
The Guardian
                 Weplay
Forrst
                 More...
PostRank
Our infrastructure
App server           App server   Utility server




      MySQL master                   Redis master




       MySQL slave                   Redis slave
Redis in Practice #1

View Counts
View counts

potential for massive amounts of simple writes/reads
valuable data, but not mission critical
lots of row contention in SQL
Redis incrementing
    $ redis-cli
    redis> incr "medium:301:views"
    (integer) 1
    redis> incr "medium:301:views"
    (integer) 2
    redis> incrby "medium:301:views" 5
    (integer) 7
    redis> decr "medium:301:views"
    (integer) 6
Redis in Practice #2

Distributed Locks
Subscribe to a Weplay Calendar




                        Subscribe to “ics”
Subscription challenges


Generally static content for long periods of time, but with
short sessions of frequent updates
Expensive to compute on the fly
Without Redis/Locking
     CANCEL EVENT                 BACKGROUND                  Pubisher
                                     QUEUE


                Queue: Publish ICS



                                                  Publish




                                                                     Contention/Redundancy


       ADD EVENT                     BACKGROUND                Pubisher
                                        QUEUE


                    Queue: Publish ICS



                                                    Publish
Redis Locking: SetNX
  redis = Redis.new
  redis.setnx "locking.key", Time.now + 2.hours
  => true
  redis.setnx "locking.key", Time.now + 2.hours
  => false
  redis.del "locking.key"
  => true¨
  redis.setnx "locking.key", Time.now + 2.hours
  => true
Redis: Obtained Lock
ADD EVENT                                  REDIS




            SETNX "group_34_publish_ics"



                   Returns: 1




                                       BACKGROUND                              PUBLISHER                       REDIS
                                          QUEUE




                                                    5 minutes later: PUBLISH....
        Queue Job: Publish.publish_ics("34")
                                                                                      DEL "group_34_publish_ics"
Redis: Locked Out
   CANCEL EVENT                                                  REDIS




                         SETNX "group_34_publish_ics"

                                Returns: 0




                  ADD EVENT                                              REDIS




                                       SETNX "group_34_publish_ics"

                                              Returns: 0
Redis in Practice #3

 Presence
“Who’s online?”
Weplay members told us
they wanted to be able
to see which of their
friends were online...
About sets
0 to N elements       Adding a value to a set
                      does not require you
Unordered
                      to check if the value
No repeated members   exists in the set first
Working with Redis sets 1/3
# SADD key, member
# Adds the specified member to the set stored at key

redis = Redis.new
redis.sadd 'my_set', 'foo'   #   =>   true
redis.sadd 'my_set', 'bar'   #   =>   true
redis.sadd 'my_set', 'bar'   #   =>   false
redis.smembers 'my_set'      #   =>   ["foo", "bar"]
Working with Redis sets 2/3
# SUNION key1 key2 ... keyN
# Returns the members of a set resulting from the union of all
# the sets stored at the specified keys.

# SUNIONSTORE <i>dstkey key1 key2 ... keyN</i></b>
# Works like SUNION but instead of being returned the resulting
# set is stored as dstkey.

redis = Redis.new
redis.sadd 'set_a', 'foo'
redis.sadd 'set_a', 'bar'
redis.sadd 'set_b', 'bar'
redis.sadd 'set_b', 'baz'
redis.sunion 'set_a', 'set_b'        # => ["foo", "baz", "bar"]

redis.sunionstore 'set_ab', 'set_a', 'set_b'
redis.smembers 'set_ab'              # => ["foo", "baz", "bar"]
Working with Redis sets 3/3
# SINTER key1 key2 ... keyN
# Returns the members that are present in all
# sets stored at the specified keys.

redis = Redis.new
redis.sadd 'set_a', 'foo'
redis.sadd 'set_a', 'bar'
redis.sadd 'set_b', 'bar'
redis.sadd 'set_b', 'baz'
redis.sinter 'set_a', 'set_b'      # => ["bar"]
Approach 1/2
Approach 2/2
Implementation 1/2
# Defining the keys

def current_key
  key(Time.now.strftime("%M"))
end

def keys_in_last_5_minutes
  now = Time.now
  times = (0..5).collect {|n| now - n.minutes }
  times.collect{ |t| key(t.strftime("%M")) }
end

def key(minute)
  "online_users_minute_#{minute}"
end
Implementation 2/2
# Tracking an Active User, and calculating who’s online

def track_user_id(id)
  key = current_key
  redis.sadd(key, id)
end

def online_user_ids
  redis.sunion(*keys_in_last_5_minutes)
end

def online_friend_ids(interested_user_id)
  redis.sunionstore("online_users", *keys_in_last_5_minutes)
  redis.sinter("online_users",
               "user:#{interested_user_id}:friend_ids")
end
Redis in Practice #4

Social Activity Feeds
Social Activity Feeds
Via SQL, Approach 1/2
 Doesn’t scale to more
 complex social graphs
 e.g. friends who are         SELECT activities.*
                                FROM activities
                                JOIN friendships f1 ON f1.from_id =
 ‘hidden’ from your feed      activities.actor_id
                                JOIN friendships f2 ON f2.to_id   =
                              activities.actor_id
 May still require multiple     WHERE f1.to_id = ? OR f2.from_id = ?
                               ORDER BY activities.id DESC

 queries to grab               LIMIT 15



 unindexed data
Via SQL, Approach 2/2                             user_id



                                                   11
                                                            activity_id



                                                               96

                                                   22          96

                                                   11          97

                                                   22          97

                                                   33          97

                                                   11          98

                                                   22          98

                          Friend: 11               11          99

    Activity: 100
                                                   11        100
               Actor 1    Friend: 22
                                        INSERTS
                                                   22        100
                         Teammate: 33
                                                   33        100
Large SQL table

Grew quickly
Difficult to maintain
Difficult to prune
Redis Lists 1/2
      redis> lpush "teams" "yankees"
      (integer) 1
      redis> lpush "teams" "redsox"
      (integer) 2
      redis> llen "teams"
      (integer) 2
      redis> lrange "teams" 0 1
      1. "redsox"
      2. "yankees"
      redis> lrange "teams" 0 -1
      1. "redsox"
      2. "yankees"
                                       LTRIM, LLEN, LRANGE
Redis Lists 2/2
      redis> ltrim "teams" 0 0
      OK
      redis> lrange "teams" 0 -1
      1. "redsox"




                                   LTRIM
via Redis, 1/2
                            LPUSH “user:11:feed”, “100”
                            LTRIM “user:11:feed”, 0, 50
                                     LPUSH 'user:11:feed', '100'        Key             Value
                      Friend: 11
                                     LTRIM 'user:11:feed', 0, 50

Activity: 100
                                                                    user:11:feed   [100,99,97,96]
                                     LPUSH 'user:22:feed', '100'
           Actor 1    Friend: 22
                                     LTRIM 'user:22:feed', 0, 50
                                                                    user:22:feed    [100,99,98]

                                     LPUSH 'user:33:feed', '100'
                     Teammate: 33
                                     LTRIM 'user:33:feed', 0, 100   user:33:feed      [100,99]
via Redis, 2/2
                                          Key             Value
                       Friend: 11


                                      user:11:feed   [100,99,97,96]

                       Friend: 22
                                     user:22:feed     [100,99,98]
 Activity: 100


            Actor 1
                                     user:33:feed       [100,99]
                      Teammate: 33




                                          Key             Value

                       New York
                                     new_york:feed      [100,67]


                         Boston       boston:feed       [100,99]
Rendering the Feed
Redis in Practice #5

Friend Suggestions
Friend Suggestions

suggest new connections based on
existing connections
expanding the social graph and
mirroring real world connections is key
The Concept

            Paul




Me         George   John




            Ringo
The Yoko Factor

            Paul




Me         George      John   Yoko




            Ringo
The Approach 1/2
           Sarah




                       2

           Frank           Donny




     Me            2

             Ted

                            Erika
The Approach 2/2
           Sarah




                   2

           Frank       Donny




     Me



             Ted
                   3
                        Erika




            Sue
ZSETS in Redis

“Sorted Sets”
Each member of the set has a score
Ordered by the score at all times
Friend Suggestions in Redis
zincrby “user:1:suggestions” 1 “donny”
zincrby “user:1:suggestions” 1 “donny”
                                          Sarah




                                          Frank   Donny




                                     Me




zincrby “user:1:suggestions” 1 “erika”
                                            Ted

                                                   Erika


zincrby “user:1:suggestions” 1 “erika”

     [ Donny   2   , Erika   2   ]
Friend Suggestions in Redis
zincrby “user:1:suggestions” 1 “erika”
                                          Sarah




                                          Frank   Donny




                                     Me



                                            Ted



zrevrange “user:1:suggestions” 0 1                 Erika




                                           Sue




     [ Erika   3   , Donny   2   ]
Redis in Practice #6

  Caching
Suitability for caching
Excellent match for managed denormalization
   ex. friendships, teams, teammates
Excellent match where you would benefit from persistence
and/or replication
Historically, not a good match for a “generational cache,” in
which you want to optimize memory use by evicting least-
recently used (LRU) keys
As an LRU cache
TTL-support since inception, but with unintuitive behavior
   Writing to volatile key replaced it and cleared the TTL
Redis 2.2 changes this behavior and adds key features:
   ability to write to, and update expiry of volatile keys
   maxmemory [bytes], maxmemory-policy [policy]
   policies: volatile-lru, volatile-ttl, volatile-random,
   allkeys-lru, allkeys-random
Easy to adapt



Namespaced Rack::Session, Rack::Cache, I18n and cache
Redis cache stores for Ruby web frameworks
   implementation is under 1,000 LOC
Contentious benchmarks
Any
questions?




                  Thanks!
    Follow us on Twitter: @noahd1 and @lukemelia
   Tell your friends in youth sports about Weplay.com

More Related Content

What's hot

Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
TO THE NEW | Technology
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
Dvir Volk
 

What's hot (20)

Redis introduction
Redis introductionRedis introduction
Redis introduction
 
An Introduction to Redis for Developers.pdf
An Introduction to Redis for Developers.pdfAn Introduction to Redis for Developers.pdf
An Introduction to Redis for Developers.pdf
 
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More! Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
 
An Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL databaseAn Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL database
 
Redis data modeling examples
Redis data modeling examplesRedis data modeling examples
Redis data modeling examples
 
Redis database
Redis databaseRedis database
Redis database
 
redis basics
redis basicsredis basics
redis basics
 
Redis overview
Redis overviewRedis overview
Redis overview
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Redis Overview
Redis OverviewRedis Overview
Redis Overview
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Redis - Usability and Use Cases
Redis - Usability and Use CasesRedis - Usability and Use Cases
Redis - Usability and Use Cases
 
Memcached
MemcachedMemcached
Memcached
 
Redis and it's data types
Redis and it's data typesRedis and it's data types
Redis and it's data types
 
Redshift performance tuning
Redshift performance tuningRedshift performance tuning
Redshift performance tuning
 
The "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedInThe "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedIn
 
Add Redis to Postgres to Make Your Microservices Go Boom!
Add Redis to Postgres to Make Your Microservices Go Boom!Add Redis to Postgres to Make Your Microservices Go Boom!
Add Redis to Postgres to Make Your Microservices Go Boom!
 
Redis cluster
Redis clusterRedis cluster
Redis cluster
 
Redis 101
Redis 101Redis 101
Redis 101
 
SQOOP PPT
SQOOP PPTSQOOP PPT
SQOOP PPT
 

Viewers also liked

Scaling Crashlytics: Building Analytics on Redis 2.6
Scaling Crashlytics: Building Analytics on Redis 2.6Scaling Crashlytics: Building Analytics on Redis 2.6
Scaling Crashlytics: Building Analytics on Redis 2.6
Crashlytics
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
Dvir Volk
 

Viewers also liked (6)

Scaling Crashlytics: Building Analytics on Redis 2.6
Scaling Crashlytics: Building Analytics on Redis 2.6Scaling Crashlytics: Building Analytics on Redis 2.6
Scaling Crashlytics: Building Analytics on Redis 2.6
 
Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)
 
High-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using RedisHigh-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using Redis
 
Redis data design by usecase
Redis data design by usecaseRedis data design by usecase
Redis data design by usecase
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
 
Everything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to askEverything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to ask
 

Similar to Redis in Practice

Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
Redis Labs
 
Redis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational DatabasesRedis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational Databases
Karel Minarik
 
WebClusters, Redis
WebClusters, RedisWebClusters, Redis
WebClusters, Redis
Filip Tepper
 
Redis学习笔记
Redis学习笔记Redis学习笔记
Redis学习笔记
yongboy
 

Similar to Redis in Practice (20)

REDIS intro and how to use redis
REDIS intro and how to use redisREDIS intro and how to use redis
REDIS intro and how to use redis
 
Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
Reinforcement Learning On Hundreds Of Thousands Of Cores: Henrique Pondedeoli...
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redis
 
10 Ways to Scale with Redis - LA Redis Meetup 2019
10 Ways to Scale with Redis - LA Redis Meetup 201910 Ways to Scale with Redis - LA Redis Meetup 2019
10 Ways to Scale with Redis - LA Redis Meetup 2019
 
Redis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational DatabasesRedis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational Databases
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
 
10 Ways to Scale Your Website Silicon Valley Code Camp 2019
10 Ways to Scale Your Website Silicon Valley Code Camp 201910 Ways to Scale Your Website Silicon Valley Code Camp 2019
10 Ways to Scale Your Website Silicon Valley Code Camp 2019
 
Amir Salihefendic: Redis - the hacker's database
Amir Salihefendic: Redis - the hacker's databaseAmir Salihefendic: Redis - the hacker's database
Amir Salihefendic: Redis - the hacker's database
 
SOLID Ruby SOLID Rails
SOLID Ruby SOLID RailsSOLID Ruby SOLID Rails
SOLID Ruby SOLID Rails
 
Redis
RedisRedis
Redis
 
Extend Redis with Modules
Extend Redis with ModulesExtend Redis with Modules
Extend Redis with Modules
 
WebClusters, Redis
WebClusters, RedisWebClusters, Redis
WebClusters, Redis
 
Advanced Redis data structures
Advanced Redis data structuresAdvanced Redis data structures
Advanced Redis data structures
 
Patterns for key-value stores
Patterns for key-value storesPatterns for key-value stores
Patterns for key-value stores
 
Drupalcamp gent - Node access
Drupalcamp gent - Node accessDrupalcamp gent - Node access
Drupalcamp gent - Node access
 
Redis
RedisRedis
Redis
 
Service Discovery & Load-Balancing under Docker 1.12.0 @ Docker Meetup #22
Service Discovery & Load-Balancing under Docker 1.12.0 @ Docker Meetup #22Service Discovery & Load-Balancing under Docker 1.12.0 @ Docker Meetup #22
Service Discovery & Load-Balancing under Docker 1.12.0 @ Docker Meetup #22
 
Redis学习笔记
Redis学习笔记Redis学习笔记
Redis学习笔记
 
Redis SoCraTes 2014
Redis SoCraTes 2014Redis SoCraTes 2014
Redis SoCraTes 2014
 
Redispresentation apac2012
Redispresentation apac2012Redispresentation apac2012
Redispresentation apac2012
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using Ballerina
 

Redis in Practice

  • 1. Redis in Practice NoSQL NYC • December 2nd, 2010 Noah Davis & Luke Melia
  • 2. About Noah & Luke Weplay.com Rubyists Running Redis in production since mid-2009 @noahd1 and @lukemelia on Twitter
  • 4. Tonight’s gameplan Fly-by intro to Redis Redis in Practice View counts Q&A throughout, please. Global locks We love being Presence interrupted. Social activity feeds Friend suggestions Caching
  • 5. Salvatore Sanfilippo Original author of Redis. @antirez on Twitter. Lives in Italy. Recently hired by VMWare. Great project leader.
  • 6. Describing Redis Remote dictionary server “advanced, fast, persistent key- value database” “Data structures server” “memcached on steroids”
  • 7. In Salvatore’s words “I see Redis definitely more as a flexible tool than as a solution specialized to solve a specific problem: his mixed soul of cache, store, and messaging server shows this very well.” - Salvatore Sanfilippo
  • 8. Qualities Written in C Few dependencies Fast Single-threaded Lots of clients available Initial release was March 2009
  • 9. Features Key-value store where a value is one of: scalar/string, list, set, sorted sets, hash Persistence: in-memory, snapshots, append-only log, VM Replication: master-slave, configureable Pub-Sub Expiry “Transaction”-y In development: Redis Cluster
  • 10. What Redis ain’t (...yet) Big data Seamless scaling Ad-hoc query tool The only data store you’ll ever need
  • 11. Who’s using Redis? VMWare Grooveshark Github Superfeedr Craigslist Ravelry EngineYard mediaFAIL The Guardian Weplay Forrst More... PostRank
  • 12. Our infrastructure App server App server Utility server MySQL master Redis master MySQL slave Redis slave
  • 13. Redis in Practice #1 View Counts
  • 14. View counts potential for massive amounts of simple writes/reads valuable data, but not mission critical lots of row contention in SQL
  • 15. Redis incrementing $ redis-cli redis> incr "medium:301:views" (integer) 1 redis> incr "medium:301:views" (integer) 2 redis> incrby "medium:301:views" 5 (integer) 7 redis> decr "medium:301:views" (integer) 6
  • 16. Redis in Practice #2 Distributed Locks
  • 17. Subscribe to a Weplay Calendar Subscribe to “ics”
  • 18. Subscription challenges Generally static content for long periods of time, but with short sessions of frequent updates Expensive to compute on the fly
  • 19. Without Redis/Locking CANCEL EVENT BACKGROUND Pubisher QUEUE Queue: Publish ICS Publish Contention/Redundancy ADD EVENT BACKGROUND Pubisher QUEUE Queue: Publish ICS Publish
  • 20. Redis Locking: SetNX redis = Redis.new redis.setnx "locking.key", Time.now + 2.hours => true redis.setnx "locking.key", Time.now + 2.hours => false redis.del "locking.key" => true¨ redis.setnx "locking.key", Time.now + 2.hours => true
  • 21. Redis: Obtained Lock ADD EVENT REDIS SETNX "group_34_publish_ics" Returns: 1 BACKGROUND PUBLISHER REDIS QUEUE 5 minutes later: PUBLISH.... Queue Job: Publish.publish_ics("34") DEL "group_34_publish_ics"
  • 22. Redis: Locked Out CANCEL EVENT REDIS SETNX "group_34_publish_ics" Returns: 0 ADD EVENT REDIS SETNX "group_34_publish_ics" Returns: 0
  • 23. Redis in Practice #3 Presence
  • 24. “Who’s online?” Weplay members told us they wanted to be able to see which of their friends were online...
  • 25. About sets 0 to N elements Adding a value to a set does not require you Unordered to check if the value No repeated members exists in the set first
  • 26. Working with Redis sets 1/3 # SADD key, member # Adds the specified member to the set stored at key redis = Redis.new redis.sadd 'my_set', 'foo' # => true redis.sadd 'my_set', 'bar' # => true redis.sadd 'my_set', 'bar' # => false redis.smembers 'my_set' # => ["foo", "bar"]
  • 27. Working with Redis sets 2/3 # SUNION key1 key2 ... keyN # Returns the members of a set resulting from the union of all # the sets stored at the specified keys. # SUNIONSTORE <i>dstkey key1 key2 ... keyN</i></b> # Works like SUNION but instead of being returned the resulting # set is stored as dstkey. redis = Redis.new redis.sadd 'set_a', 'foo' redis.sadd 'set_a', 'bar' redis.sadd 'set_b', 'bar' redis.sadd 'set_b', 'baz' redis.sunion 'set_a', 'set_b' # => ["foo", "baz", "bar"] redis.sunionstore 'set_ab', 'set_a', 'set_b' redis.smembers 'set_ab' # => ["foo", "baz", "bar"]
  • 28. Working with Redis sets 3/3 # SINTER key1 key2 ... keyN # Returns the members that are present in all # sets stored at the specified keys. redis = Redis.new redis.sadd 'set_a', 'foo' redis.sadd 'set_a', 'bar' redis.sadd 'set_b', 'bar' redis.sadd 'set_b', 'baz' redis.sinter 'set_a', 'set_b' # => ["bar"]
  • 31. Implementation 1/2 # Defining the keys def current_key   key(Time.now.strftime("%M")) end def keys_in_last_5_minutes   now = Time.now   times = (0..5).collect {|n| now - n.minutes }   times.collect{ |t| key(t.strftime("%M")) } end def key(minute)   "online_users_minute_#{minute}" end
  • 32. Implementation 2/2 # Tracking an Active User, and calculating who’s online def track_user_id(id)   key = current_key   redis.sadd(key, id) end def online_user_ids   redis.sunion(*keys_in_last_5_minutes) end def online_friend_ids(interested_user_id)   redis.sunionstore("online_users", *keys_in_last_5_minutes)   redis.sinter("online_users", "user:#{interested_user_id}:friend_ids") end
  • 33. Redis in Practice #4 Social Activity Feeds
  • 35. Via SQL, Approach 1/2 Doesn’t scale to more complex social graphs e.g. friends who are SELECT activities.* FROM activities JOIN friendships f1 ON f1.from_id = ‘hidden’ from your feed activities.actor_id JOIN friendships f2 ON f2.to_id = activities.actor_id May still require multiple WHERE f1.to_id = ? OR f2.from_id = ? ORDER BY activities.id DESC queries to grab LIMIT 15 unindexed data
  • 36. Via SQL, Approach 2/2 user_id 11 activity_id 96 22 96 11 97 22 97 33 97 11 98 22 98 Friend: 11 11 99 Activity: 100 11 100 Actor 1 Friend: 22 INSERTS 22 100 Teammate: 33 33 100
  • 37. Large SQL table Grew quickly Difficult to maintain Difficult to prune
  • 38. Redis Lists 1/2 redis> lpush "teams" "yankees" (integer) 1 redis> lpush "teams" "redsox" (integer) 2 redis> llen "teams" (integer) 2 redis> lrange "teams" 0 1 1. "redsox" 2. "yankees" redis> lrange "teams" 0 -1 1. "redsox" 2. "yankees" LTRIM, LLEN, LRANGE
  • 39. Redis Lists 2/2 redis> ltrim "teams" 0 0 OK redis> lrange "teams" 0 -1 1. "redsox" LTRIM
  • 40. via Redis, 1/2 LPUSH “user:11:feed”, “100” LTRIM “user:11:feed”, 0, 50 LPUSH 'user:11:feed', '100' Key Value Friend: 11 LTRIM 'user:11:feed', 0, 50 Activity: 100 user:11:feed [100,99,97,96] LPUSH 'user:22:feed', '100' Actor 1 Friend: 22 LTRIM 'user:22:feed', 0, 50 user:22:feed [100,99,98] LPUSH 'user:33:feed', '100' Teammate: 33 LTRIM 'user:33:feed', 0, 100 user:33:feed [100,99]
  • 41. via Redis, 2/2 Key Value Friend: 11 user:11:feed [100,99,97,96] Friend: 22 user:22:feed [100,99,98] Activity: 100 Actor 1 user:33:feed [100,99] Teammate: 33 Key Value New York new_york:feed [100,67] Boston boston:feed [100,99]
  • 43. Redis in Practice #5 Friend Suggestions
  • 44. Friend Suggestions suggest new connections based on existing connections expanding the social graph and mirroring real world connections is key
  • 45. The Concept Paul Me George John Ringo
  • 46. The Yoko Factor Paul Me George John Yoko Ringo
  • 47. The Approach 1/2 Sarah 2 Frank Donny Me 2 Ted Erika
  • 48. The Approach 2/2 Sarah 2 Frank Donny Me Ted 3 Erika Sue
  • 49. ZSETS in Redis “Sorted Sets” Each member of the set has a score Ordered by the score at all times
  • 50. Friend Suggestions in Redis zincrby “user:1:suggestions” 1 “donny” zincrby “user:1:suggestions” 1 “donny” Sarah Frank Donny Me zincrby “user:1:suggestions” 1 “erika” Ted Erika zincrby “user:1:suggestions” 1 “erika” [ Donny 2 , Erika 2 ]
  • 51. Friend Suggestions in Redis zincrby “user:1:suggestions” 1 “erika” Sarah Frank Donny Me Ted zrevrange “user:1:suggestions” 0 1 Erika Sue [ Erika 3 , Donny 2 ]
  • 52. Redis in Practice #6 Caching
  • 53. Suitability for caching Excellent match for managed denormalization ex. friendships, teams, teammates Excellent match where you would benefit from persistence and/or replication Historically, not a good match for a “generational cache,” in which you want to optimize memory use by evicting least- recently used (LRU) keys
  • 54. As an LRU cache TTL-support since inception, but with unintuitive behavior Writing to volatile key replaced it and cleared the TTL Redis 2.2 changes this behavior and adds key features: ability to write to, and update expiry of volatile keys maxmemory [bytes], maxmemory-policy [policy] policies: volatile-lru, volatile-ttl, volatile-random, allkeys-lru, allkeys-random
  • 55. Easy to adapt Namespaced Rack::Session, Rack::Cache, I18n and cache Redis cache stores for Ruby web frameworks implementation is under 1,000 LOC
  • 57. Any questions? Thanks! Follow us on Twitter: @noahd1 and @lukemelia Tell your friends in youth sports about Weplay.com

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. http://antirez.com/m/p.php?i=220\nvolatile-lru remove a key among the ones with an expire set, trying to remove keys not recently used.\nvolatile-ttl remove a key among the ones with an expire set, trying to remove keys with short remaining time to live.\nvolatile-random remove a random key among the ones with an expire set.\nallkeys-lru like volatile-lru, but will remove every kind of key, both normal keys or keys with an expire set.\nallkeys-random like volatile-random, but will remove every kind of keys, both normal keys and keys with an expire set.\n\n
  55. Another 1500 LOC for specs\n
  56. \n
  57. \n