SlideShare a Scribd company logo
1 of 83
Download to read offline
Redis & Groovy & Grails



                               by Ted Naleid
                               http://naleid.com

Monday, June 20, 2011
“Redis is a collection of data
                        structures exposed over the
                                  network”


                                                  from: http://nosql.mypopescu.com/post/5403851771/what-is-redis

Monday, June 20, 2011
key/value store

               like memcached on steroids


Monday, June 20, 2011
Strings, Integers,
                                Lists, Hashes,
                              Sets & Sorted Sets
                        (& commonly expected operations with each data type)




Monday, June 20, 2011
in-memory storage



Monday, June 20, 2011
single-threaded



Monday, June 20, 2011
fast



Monday, June 20, 2011
“Memory is the new Disk,
                         Disk is the new Tape”
                                 - Jim Gray




Monday, June 20, 2011
Relative Latency
                           CPU Register - 1x
                            L2 Cache - 10x
                            Memory - 100x
                           Disk - 10,000,000x




                                                analogy from “Redis - Memory as the New Disk” - Tim Lossen &
                                                   http://en.wikipedia.org/wiki/Orders_of_magnitude_(speed)
Monday, June 20, 2011
CPU Register
                            1 yard




                                       photo: http://www.flickr.com/photos/limonada/904754668/

Monday, June 20, 2011
L2 Cache
                         10 yards




                                    photo: http://www.flickr.com/photos/plentyofants/2749262107

Monday, June 20, 2011
Memory
                        100 yards




                                    photo: http://www.flickr.com/photos/billmcintyre/264905933

Monday, June 20, 2011
Disk
        Minneapolis to New York to Miami
                   to Seattle
                        ~5600 miles




Monday, June 20, 2011
Simple wire protocol that
                              matches API


Monday, June 20, 2011
% telnet localhost 6379
    Escape character is '^]'.
    set foo bar
    +OK
    get foo
    $3
    bar
    rpush mylist first
    :1
    rpush mylist second
    :2
    lrange mylist 0 -1
    *2
    $5
    first
    $6
    second


Monday, June 20, 2011
clients for every* language

             *well not every language, but all the popular/semi-popular ones, you can easily write one if
                                           your language doesn’t have one




Monday, June 20, 2011
No dependencies
                            (451KB download)




Monday, June 20, 2011
Used in production by high
                  traffic sites that you’ve used


Monday, June 20, 2011
stackoverflow, craigslist,
                         github, disqus, digg &
                         blizzard entertainment


Monday, June 20, 2011
financially supported by
                         VMware/SpringSource


Monday, June 20, 2011
simple data structures make
                       redis flexible


Monday, June 20, 2011
write-through caching/
                             memoization


Monday, June 20, 2011
producer/consumer
                         message queues


Monday, June 20, 2011
publish/subscribe



Monday, June 20, 2011
atomic sequences/counters



Monday, June 20, 2011
other uses...
                             distributed locks, tag clouds, session tokens,
                        auto-complete prefixes, API rate limiting, leaderboards,
                        capped logs, random set items, A/B testing data storage,
                               unique per user product pricing/sorting




Monday, June 20, 2011
Redis Commands



Monday, June 20, 2011
Great Online Reference
                               http://redis.io/commands




Monday, June 20, 2011
Strings
                                            set


                        Redis REPL                            Groovy



                 > set foo bar                          redis.set("foo", "bar")
                                      foo         bar
                 OK                                     OK




Monday, June 20, 2011
Strings
                                            get


                        Redis REPL                            Groovy


                                      foo         bar

                 > get foo                              redis.get("foo")
                 "bar"                                  "bar"

                                                  bar




Monday, June 20, 2011
Exists
                                     exists (check key existence)


                        Redis REPL                                   Groovy


                                              foo     (nil)

           > exists foo                                             redis.exists("foo")
           (integer) 0                                              <= false

                                                        0




Monday, June 20, 2011
Integers
                                     incr (increment)


                        Redis REPL                       Groovy


                                        foo      1

           > incr foo                                   redis.incr("foo")
           (integer) 1                                  <= 1

                                                 1




Monday, June 20, 2011
Integers
                                     decr (decrement)


                        Redis REPL                       Groovy


                                        foo      0

           > decr foo                                   redis.decr("foo")
           (integer) 0                                  <= 0

                                                 0




Monday, June 20, 2011
Lists
                                     rpush (right push)


                        Redis REPL                                 Groovy



           > rpush foo baz                                redis.rpush("foo", "baz")
                                         foo     baz
           (integer) 1                                    <= 1




Monday, June 20, 2011
Lists
                                     rpush (right push)


                        Redis REPL                                 Groovy



           > rpush foo qux                                redis.rpush("foo", "qux")
                                      foo     baz qux
           (integer) 2                                    <= 2




Monday, June 20, 2011
Lists
                                     lpush (left push)


                        Redis REPL                                    Groovy



           > lpush foo bar                                   redis.lpush("foo", "bar")
                                     foo     bar   baz qux
           (integer) 3                                       <= 3




Monday, June 20, 2011
Lists
                                     lrange (slice of list)


                        Redis REPL                                     Groovy


                                      foo      bar   baz qux
           > lrange foo 0 -1                                   redis.lrange("foo", 0, -1)
           1) "bar"                                            <= [bar, baz, qux]
           2) "baz"
           3) "qux"
                                               bar   baz qux




Monday, June 20, 2011
Lists
                                     lrange (slice of list)


                        Redis REPL                                    Groovy


                                      foo      bar   baz qux
           > lrange foo 0 1                                    redis.lrange("foo", 0, 1)
           1) "bar"                                            <= [bar, baz]
           2) "baz"
                                                 bar   baz




Monday, June 20, 2011
Lists
                                     lpop (left pop)


                        Redis REPL                       Groovy


                                     foo      baz qux

           > lpop foo                                   redis.lpop("foo")
           "bar"                                        <= "bar"

                                                bar




Monday, June 20, 2011
Lists
                                     rpop (right pop)


                        Redis REPL                       Groovy


                                        foo     baz

           > rpop foo                                   redis.rpop("foo")
           "qux"                                        <= "qux"

                                                qux




Monday, June 20, 2011
Hashes
                                     hset (set key → value)


                        Redis REPL                                        Groovy



           > hset foo bar baz                                 redis.hset("foo", "bar", "baz")
                                     foo     bar    baz
           (integer) 1                                        <= 1




Monday, June 20, 2011
Hashes
                                     hset (set key → value)


                        Redis REPL                                         Groovy



                                              bar     baz
           > hset foo qux quxx                                redis.hset("foo", "qux", "quxx")
                                      foo
           (integer) 1                                        <= 1
                                              qux     quxx




Monday, June 20, 2011
Hashes
                                     hget (get value for key)


                        Redis REPL                                       Groovy

                                               bar         baz
                                      foo
                                               qux         quxx
           > hget foo bar                                         redis.hget("foo", "bar")
           "baz"                                                  <= "baz"

                                                     baz




Monday, June 20, 2011
Hashes
                                     hgetall (get all keys/values)


                        Redis REPL                                          Groovy
                                                   bar    baz
                                          foo
           > hgetall foo                           qux    quxx

           1) "bar"                                                  redis.hgetAll("foo")
           2) "baz"                                                  <= [bar:baz, qux:quxx]
           3) "qux"
           4) "quxx"                               bar    baz

                                                  qux     quxx




Monday, June 20, 2011
Hashes
                                     hvals (hash values)


                        Redis REPL                              Groovy
                                              bar     baz
                                      foo
                                              qux     quxx

           > hvals foo                                       redis.hvals("foo")
           1) "baz"                                          <= [baz, quxx]
           2) "quxx"
                                                baz quxx




Monday, June 20, 2011
Hashes
                                     hkeys (hash keys)


                        Redis REPL                            Groovy
                                             bar     baz
                                     foo
                                             qux    quxx

           > hkeys foo                                     redis.hkeys("foo")
           1) "bar"                                        <= [bar, qux]
           2) "qux"
                                               bar qux




Monday, June 20, 2011
Sets
                                     sadd (set add)


                        Redis REPL                           Groovy



            > sadd m1 jan                             redis.sadd("m1", "jan")
                                       m1      jan
            (integer) 1                               <= 1




Monday, June 20, 2011
Sets
                                     sadd (set add)


                        Redis REPL                          Groovy



                                               feb
            > sadd m1 feb                             redis.sadd("m1", "feb")
                                       m1
            (integer) 1                               <= 1
                                               jan




Monday, June 20, 2011
Sets
                                     sismember (membership test)


                        Redis REPL                                           Groovy
                                                     feb
                                              m1
                                                     jan
            > sismember m1 jan                                     redis.sismember("m1", "jan")
            (integer) 1                                            <= true

                                                      1




Monday, June 20, 2011
Sets
                                     sismember (membership test)


                        Redis REPL                                          Groovy
                                                     feb
                                              m1
                                                     jan
            > sismember m1 mar                                     redis.sismember("m1", "mar")
            (integer) 0                                            <= false

                                                      0




Monday, June 20, 2011
Sets
                                     smembers (get full set)


                        Redis REPL                                   Groovy
                                                    feb
                                           m1
                                                    jan
           > smembers m1                                       redis.smembers("m1")
           1) "feb"                                            <= [feb, jan]
           2) "jan"
                                                    feb

                                                    jan



Monday, June 20, 2011
Sets
                                     sinter (set intersection)


                        Redis REPL                                       Groovy
                                             feb            feb
                                     m1             m2
                                             jan            mar
         > sinter m1 m2                                           redis.sinter("m1", "m2")
         1) "feb"                                                 <= ["feb"]

                                                     feb




Monday, June 20, 2011
Sets
                                      sdiff (set difference)


                        Redis REPL                                      Groovy
                                             feb           feb
                                     m1            m2
                                             jan           mar
          > sdiff m1 m2                                          redis.sdiff("m1", "m2")
          1) "jan"                                               <= ["jan"]

                                                    jan




Monday, June 20, 2011
Sets
                                          sunion (set union)


                        Redis REPL                                        Groovy
                                               feb             feb
                                     m1              m2
         > sunion m1 m2                        jan             mar
         1) "mar"                                                    redis.sunion("m1", "m2")
         2) "jan"                                     mar            <= ["mar", "jan", "feb"]
         3) "feb"
                                                       jan

                                                      feb


Monday, June 20, 2011
Sorted Sets
                                      zadd (add with score)


                        Redis REPL                                    Groovy



          > zadd z1 1 jan                                     redis.zadd("z1", 1, "jan")
                                           z1      1 jan
          (integer) 1                                         <= 1




Monday, June 20, 2011
Sorted Sets
                                     zscore (score for member)


                        Redis REPL                                       Groovy
                                                    1 jan

                                             z1     2 feb

           > zscore z1 feb                          3 mar        redis.zscore("z1", "feb")
           "2"                                                   <= 2.0


                                                      2




Monday, June 20, 2011
Sorted Sets
                                        zrange (sorted subset)


                        Redis REPL                                          Groovy
                                                   1 jan

                                           z1      2 feb
           > zrange z1 0 1 withscores
           1) "jan"                                3 mar    redis.zrangeWithScores("z1", 0, 1)
           2) "1"                                           <= [["jan", 1], ["feb", 2]]
           3) "feb"
           4) "2"
                                                   1 jan

                                                   2 feb


Monday, June 20, 2011
Sorted Sets
                                zrangebyscore (subset having score range)


                        Redis REPL                                               Groovy
                                                       1 jan

                                               z1      2 feb
         > zrangebyscore z1 2 3 withscores
         1) "feb"                                      3 mar   redis.zrangeByScoreWithScores("z1",2,3)
         2) "2"                                                <= [["feb", 2], ["mar", 3]]
         3) "mar"
         4) "3"
                                                       2 feb

                                                       3 mar


Monday, June 20, 2011
Groovy Usage



Monday, June 20, 2011
Grape @Grab Annotation

          #! /usr/bin/env groovy
          @Grab('redis.clients:jedis:2.0.0')

          def redis = new redis.clients.jedis.Jedis("localhost")

          assert "PONG" == redis.ping()



Monday, June 20, 2011
Producer/Consumer
                             Example


Monday, June 20, 2011
Producer
                          pushes work on a list with lpush




         @Grab('redis.clients:jedis:2.0.0')

         redis = new redis.clients.jedis.Jedis("localhost")

         args.each { redis.lpush("welcome-wagon", it) }




Monday, June 20, 2011
Consumer
                        uses blpop (blocking left pop from list)


         @Grab('redis.clients:jedis:2.0.0')

         redis = new redis.clients.jedis.Jedis("localhost")

         println "Joining the welcome-wagon!"

         while (true) {
             def name = redis.blpop(0, "welcome-wagon")[1]
             println "Welcome ${name}!"
         }

Monday, June 20, 2011
Mass Producer
                        srandmember to randomly pick female name from set


         @Grab('redis.clients:jedis:2.0.0')
         redis = new redis.clients.jedis.Jedis("localhost")

         if (!redis.exists("female-names")) {
            new File("./female-names.txt").eachLine {redis.sadd("female-names",it)}
         }

         for (i in 1..100000) {
            redis.lpush("welcome-wagon", redis.srandmember("female-names"))
            if (i % 1000 == 0) println "Adding $i"
         }

                                                    female-names.txt from: http://antirez.com/post/autocomplete-with-redis.html
Monday, June 20, 2011
Groovy Demo



Monday, June 20, 2011
Grails Redis Plugin
                        https://github.com/grails-plugins/grails-redis




Monday, June 20, 2011
Plugin Config
                                        in Config.xml




          grails {
              redis {
                   poolConfig {
                       // jedis pool specific tweaks here, see jedis docs & src
                       // ex: numTestsPerEvictionRun = 4
                   }
                   port = 6379
                   host = "localhost"
              }
          }


Monday, June 20, 2011
Provides Caching Through
                              Memoization


Monday, June 20, 2011
RedisTagLib

          <redis:memoize key="mykey" expire="3600">
              <!--
                   insert expensive to generate GSP content here

                        content will be executed once, subsequent calls
                        will pull from redis (redis.get(“mykey”)) till the key expires
              -->
          </redis:memoize>



Monday, June 20, 2011
RedisService
                          Spring bean wraps pool connection




          // overrides propertyMissing and methodMissing to delegate to redis
          def redisService

          redisService.foo = "bar"
          assert "bar" == redisService.foo

          redisService.sadd("months", "february")
          assert true == redisService.sismember("months", "february")



Monday, June 20, 2011
RedisService
                        template methods manage pooled Redis connection




          redisService.withRedis { Jedis redis ->
              redis.set("foo", "bar")
          }




Monday, June 20, 2011
RedisService
                            template methods manage pooled Redis connection




          redisService.withRedis { Jedis redis ->

                        redisService.withTransaction { Transaction transaction ->
                            transaction.set("qux", "baz")
                            assertNull redis.get("qux")
                        }

                        assertEquals "baz", redis.get("qux")
          }



Monday, June 20, 2011
RedisService
                                   String memoization



          redisService.memoize("my-key") { Jedis redis ->
              // expensive operation we only want to execute once
          }


          def ONE_HOUR = 3600 // with optional timeout in seconds
          redisService.memoize("my-key-with-timeout", ONE_HOUR) { Jedis redis ->
              // expensive operation we want to execute every hour
          }



Monday, June 20, 2011
RedisService
                        Domain Class memoization (stores IDs hydrates from DB)




           def key = "user:$id:friends-books"

           redisService.memoizeDomainList(Book, key, ONE_HOUR) { redis ->
               // expensive process to calculate all friend’s books
               // stores list of Book ids, hydrates them from DB
           }




Monday, June 20, 2011
Example
                        Showing Products with Sort/Filter/Pagination Criteria




Monday, June 20, 2011
Other Memoization Methods
                        memoizeHash, memoizeHashField,
                         memoizeScore (sorted set score)




Monday, June 20, 2011
Grails Redis-GORM Plugin
                          http://grails.github.com/inconsequential/redis/




Monday, June 20, 2011
Uses SpringData to abstract
                          data layer


Monday, June 20, 2011
Can be used in conjunction
                        with Hibernate


Monday, June 20, 2011
Partial support for GORM
     including Dynamic Finders, Criteria, Named Queries and “Transactions”




Monday, June 20, 2011
Limitations
                        It requires explicit index mapping on fields you want to query

          package com.example

          class Author {

                        String name

                        static mapWith = "redis"
                        static hasMany = [books: Book]

                        static mapping = {
                            name index:true
                        }
          }
Monday, June 20, 2011
Under The Covers
                        MONITOR output for new Author(name: "Stephen King").save()




          1308027697.922839       "INCR" "com.example.Author.next_id"
          1308027697.940021       "HMSET" "com.example.Author:1" "name" "Stephen King" "version" "0"
          1308027697.940412       "SADD" "com.example.Author.all" "1"
          1308027697.943318       "SADD" "com.example.Author:id:1" "1"
          1308027697.943763       "ZADD" "com.example.Author:id:sorted" "1.0" "1"
          1308027697.944911       "SADD" "com.example.Author:name:Stephen+King" "1"




Monday, June 20, 2011
Questions?



Monday, June 20, 2011

More Related Content

What's hot

Voldemort : Prototype to Production
Voldemort : Prototype to ProductionVoldemort : Prototype to Production
Voldemort : Prototype to ProductionVinoth Chandar
 
GS리테일 통합물류시스템 구축 요구사항명세서
GS리테일 통합물류시스템 구축 요구사항명세서GS리테일 통합물류시스템 구축 요구사항명세서
GS리테일 통합물류시스템 구축 요구사항명세서Hyeonji Jeong
 
Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz SAurabh PRajapati
 
Asynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAsynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAlvaro Sanchez-Mariscal
 
Thrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonThrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonIgor Anishchenko
 
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptx
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptxMicrosoft_Databricks Datathon - Submission Deck TEMPLATE.pptx
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptxAbdoulaye DOUCOURE
 
Introduction to Drools
Introduction to DroolsIntroduction to Drools
Introduction to Droolsgiurca
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaSanjeev Tripathi
 
JPA - Java Persistence API
JPA - Java Persistence APIJPA - Java Persistence API
JPA - Java Persistence APIThomas Wöhlke
 
Working with Legacy Code
Working with Legacy CodeWorking with Legacy Code
Working with Legacy CodeEyal Golan
 
Code Review Best Practices
Code Review Best PracticesCode Review Best Practices
Code Review Best PracticesTrisha Gee
 
Clean Code - Writing code for human
Clean Code - Writing code for humanClean Code - Writing code for human
Clean Code - Writing code for humanNETKO Solution
 
React Native Firebase Realtime Database + Authentication
React Native Firebase Realtime Database + AuthenticationReact Native Firebase Realtime Database + Authentication
React Native Firebase Realtime Database + AuthenticationKobkrit Viriyayudhakorn
 
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇CODE BLUE
 
Django with MongoDB using MongoEngine
Django with MongoDB using MongoEngineDjango with MongoDB using MongoEngine
Django with MongoDB using MongoEngineRakesh Kumar
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to RedisDvir Volk
 

What's hot (20)

Voldemort : Prototype to Production
Voldemort : Prototype to ProductionVoldemort : Prototype to Production
Voldemort : Prototype to Production
 
GS리테일 통합물류시스템 구축 요구사항명세서
GS리테일 통합물류시스템 구축 요구사항명세서GS리테일 통합물류시스템 구축 요구사항명세서
GS리테일 통합물류시스템 구축 요구사항명세서
 
Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz
 
Asynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAsynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applications
 
Thrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonThrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased Comparison
 
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptx
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptxMicrosoft_Databricks Datathon - Submission Deck TEMPLATE.pptx
Microsoft_Databricks Datathon - Submission Deck TEMPLATE.pptx
 
Introduction to Drools
Introduction to DroolsIntroduction to Drools
Introduction to Drools
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
JPA - Java Persistence API
JPA - Java Persistence APIJPA - Java Persistence API
JPA - Java Persistence API
 
Working with Legacy Code
Working with Legacy CodeWorking with Legacy Code
Working with Legacy Code
 
Java
JavaJava
Java
 
Code Review Best Practices
Code Review Best PracticesCode Review Best Practices
Code Review Best Practices
 
Clean Code - Writing code for human
Clean Code - Writing code for humanClean Code - Writing code for human
Clean Code - Writing code for human
 
4. logistikanin esaslari, talibov ceyhun
4. logistikanin   esaslari, talibov ceyhun4. logistikanin   esaslari, talibov ceyhun
4. logistikanin esaslari, talibov ceyhun
 
React Native Firebase Realtime Database + Authentication
React Native Firebase Realtime Database + AuthenticationReact Native Firebase Realtime Database + Authentication
React Native Firebase Realtime Database + Authentication
 
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
 
Android Data Storagefinal
Android Data StoragefinalAndroid Data Storagefinal
Android Data Storagefinal
 
Django with MongoDB using MongoEngine
Django with MongoDB using MongoEngineDjango with MongoDB using MongoEngine
Django with MongoDB using MongoEngine
 
Hibernate in Action
Hibernate in ActionHibernate in Action
Hibernate in Action
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 

Viewers also liked

Migrating from MySQL to MongoDB at Wordnik
Migrating from MySQL to MongoDB at WordnikMigrating from MySQL to MongoDB at Wordnik
Migrating from MySQL to MongoDB at WordnikTony Tam
 
MongoDB 2.8 Replication Internals: Fitting it all together
MongoDB 2.8 Replication Internals: Fitting it all togetherMongoDB 2.8 Replication Internals: Fitting it all together
MongoDB 2.8 Replication Internals: Fitting it all togetherScott Hernandez
 
redis 适用场景与实现
redis 适用场景与实现redis 适用场景与实现
redis 适用场景与实现iammutex
 
Lessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistLessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistJeremy Zawodny
 
深入了解Redis
深入了解Redis深入了解Redis
深入了解Redisiammutex
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday DeveloperRoss Tuck
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in PracticeNoah Davis
 

Viewers also liked (9)

Redis介绍
Redis介绍Redis介绍
Redis介绍
 
Migrating from MySQL to MongoDB at Wordnik
Migrating from MySQL to MongoDB at WordnikMigrating from MySQL to MongoDB at Wordnik
Migrating from MySQL to MongoDB at Wordnik
 
MongoDB 2.8 Replication Internals: Fitting it all together
MongoDB 2.8 Replication Internals: Fitting it all togetherMongoDB 2.8 Replication Internals: Fitting it all together
MongoDB 2.8 Replication Internals: Fitting it all together
 
redis 适用场景与实现
redis 适用场景与实现redis 适用场景与实现
redis 适用场景与实现
 
Lessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistLessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at Craigslist
 
深入了解Redis
深入了解Redis深入了解Redis
深入了解Redis
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday Developer
 
A Brief MongoDB Intro
A Brief MongoDB IntroA Brief MongoDB Intro
A Brief MongoDB Intro
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in Practice
 

Recently uploaded

Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 

Recently uploaded (20)

Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 

Redis & Groovy integration for caching and messaging

  • 1. Redis & Groovy & Grails by Ted Naleid http://naleid.com Monday, June 20, 2011
  • 2. “Redis is a collection of data structures exposed over the network” from: http://nosql.mypopescu.com/post/5403851771/what-is-redis Monday, June 20, 2011
  • 3. key/value store like memcached on steroids Monday, June 20, 2011
  • 4. Strings, Integers, Lists, Hashes, Sets & Sorted Sets (& commonly expected operations with each data type) Monday, June 20, 2011
  • 8. “Memory is the new Disk, Disk is the new Tape” - Jim Gray Monday, June 20, 2011
  • 9. Relative Latency CPU Register - 1x L2 Cache - 10x Memory - 100x Disk - 10,000,000x analogy from “Redis - Memory as the New Disk” - Tim Lossen & http://en.wikipedia.org/wiki/Orders_of_magnitude_(speed) Monday, June 20, 2011
  • 10. CPU Register 1 yard photo: http://www.flickr.com/photos/limonada/904754668/ Monday, June 20, 2011
  • 11. L2 Cache 10 yards photo: http://www.flickr.com/photos/plentyofants/2749262107 Monday, June 20, 2011
  • 12. Memory 100 yards photo: http://www.flickr.com/photos/billmcintyre/264905933 Monday, June 20, 2011
  • 13. Disk Minneapolis to New York to Miami to Seattle ~5600 miles Monday, June 20, 2011
  • 14. Simple wire protocol that matches API Monday, June 20, 2011
  • 15. % telnet localhost 6379 Escape character is '^]'. set foo bar +OK get foo $3 bar rpush mylist first :1 rpush mylist second :2 lrange mylist 0 -1 *2 $5 first $6 second Monday, June 20, 2011
  • 16. clients for every* language *well not every language, but all the popular/semi-popular ones, you can easily write one if your language doesn’t have one Monday, June 20, 2011
  • 17. No dependencies (451KB download) Monday, June 20, 2011
  • 18. Used in production by high traffic sites that you’ve used Monday, June 20, 2011
  • 19. stackoverflow, craigslist, github, disqus, digg & blizzard entertainment Monday, June 20, 2011
  • 20. financially supported by VMware/SpringSource Monday, June 20, 2011
  • 21. simple data structures make redis flexible Monday, June 20, 2011
  • 22. write-through caching/ memoization Monday, June 20, 2011
  • 23. producer/consumer message queues Monday, June 20, 2011
  • 26. other uses... distributed locks, tag clouds, session tokens, auto-complete prefixes, API rate limiting, leaderboards, capped logs, random set items, A/B testing data storage, unique per user product pricing/sorting Monday, June 20, 2011
  • 28. Great Online Reference http://redis.io/commands Monday, June 20, 2011
  • 29. Strings set Redis REPL Groovy > set foo bar redis.set("foo", "bar") foo bar OK OK Monday, June 20, 2011
  • 30. Strings get Redis REPL Groovy foo bar > get foo redis.get("foo") "bar" "bar" bar Monday, June 20, 2011
  • 31. Exists exists (check key existence) Redis REPL Groovy foo (nil) > exists foo redis.exists("foo") (integer) 0 <= false 0 Monday, June 20, 2011
  • 32. Integers incr (increment) Redis REPL Groovy foo 1 > incr foo redis.incr("foo") (integer) 1 <= 1 1 Monday, June 20, 2011
  • 33. Integers decr (decrement) Redis REPL Groovy foo 0 > decr foo redis.decr("foo") (integer) 0 <= 0 0 Monday, June 20, 2011
  • 34. Lists rpush (right push) Redis REPL Groovy > rpush foo baz redis.rpush("foo", "baz") foo baz (integer) 1 <= 1 Monday, June 20, 2011
  • 35. Lists rpush (right push) Redis REPL Groovy > rpush foo qux redis.rpush("foo", "qux") foo baz qux (integer) 2 <= 2 Monday, June 20, 2011
  • 36. Lists lpush (left push) Redis REPL Groovy > lpush foo bar redis.lpush("foo", "bar") foo bar baz qux (integer) 3 <= 3 Monday, June 20, 2011
  • 37. Lists lrange (slice of list) Redis REPL Groovy foo bar baz qux > lrange foo 0 -1 redis.lrange("foo", 0, -1) 1) "bar" <= [bar, baz, qux] 2) "baz" 3) "qux" bar baz qux Monday, June 20, 2011
  • 38. Lists lrange (slice of list) Redis REPL Groovy foo bar baz qux > lrange foo 0 1 redis.lrange("foo", 0, 1) 1) "bar" <= [bar, baz] 2) "baz" bar baz Monday, June 20, 2011
  • 39. Lists lpop (left pop) Redis REPL Groovy foo baz qux > lpop foo redis.lpop("foo") "bar" <= "bar" bar Monday, June 20, 2011
  • 40. Lists rpop (right pop) Redis REPL Groovy foo baz > rpop foo redis.rpop("foo") "qux" <= "qux" qux Monday, June 20, 2011
  • 41. Hashes hset (set key → value) Redis REPL Groovy > hset foo bar baz redis.hset("foo", "bar", "baz") foo bar baz (integer) 1 <= 1 Monday, June 20, 2011
  • 42. Hashes hset (set key → value) Redis REPL Groovy bar baz > hset foo qux quxx redis.hset("foo", "qux", "quxx") foo (integer) 1 <= 1 qux quxx Monday, June 20, 2011
  • 43. Hashes hget (get value for key) Redis REPL Groovy bar baz foo qux quxx > hget foo bar redis.hget("foo", "bar") "baz" <= "baz" baz Monday, June 20, 2011
  • 44. Hashes hgetall (get all keys/values) Redis REPL Groovy bar baz foo > hgetall foo qux quxx 1) "bar" redis.hgetAll("foo") 2) "baz" <= [bar:baz, qux:quxx] 3) "qux" 4) "quxx" bar baz qux quxx Monday, June 20, 2011
  • 45. Hashes hvals (hash values) Redis REPL Groovy bar baz foo qux quxx > hvals foo redis.hvals("foo") 1) "baz" <= [baz, quxx] 2) "quxx" baz quxx Monday, June 20, 2011
  • 46. Hashes hkeys (hash keys) Redis REPL Groovy bar baz foo qux quxx > hkeys foo redis.hkeys("foo") 1) "bar" <= [bar, qux] 2) "qux" bar qux Monday, June 20, 2011
  • 47. Sets sadd (set add) Redis REPL Groovy > sadd m1 jan redis.sadd("m1", "jan") m1 jan (integer) 1 <= 1 Monday, June 20, 2011
  • 48. Sets sadd (set add) Redis REPL Groovy feb > sadd m1 feb redis.sadd("m1", "feb") m1 (integer) 1 <= 1 jan Monday, June 20, 2011
  • 49. Sets sismember (membership test) Redis REPL Groovy feb m1 jan > sismember m1 jan redis.sismember("m1", "jan") (integer) 1 <= true 1 Monday, June 20, 2011
  • 50. Sets sismember (membership test) Redis REPL Groovy feb m1 jan > sismember m1 mar redis.sismember("m1", "mar") (integer) 0 <= false 0 Monday, June 20, 2011
  • 51. Sets smembers (get full set) Redis REPL Groovy feb m1 jan > smembers m1 redis.smembers("m1") 1) "feb" <= [feb, jan] 2) "jan" feb jan Monday, June 20, 2011
  • 52. Sets sinter (set intersection) Redis REPL Groovy feb feb m1 m2 jan mar > sinter m1 m2 redis.sinter("m1", "m2") 1) "feb" <= ["feb"] feb Monday, June 20, 2011
  • 53. Sets sdiff (set difference) Redis REPL Groovy feb feb m1 m2 jan mar > sdiff m1 m2 redis.sdiff("m1", "m2") 1) "jan" <= ["jan"] jan Monday, June 20, 2011
  • 54. Sets sunion (set union) Redis REPL Groovy feb feb m1 m2 > sunion m1 m2 jan mar 1) "mar" redis.sunion("m1", "m2") 2) "jan" mar <= ["mar", "jan", "feb"] 3) "feb" jan feb Monday, June 20, 2011
  • 55. Sorted Sets zadd (add with score) Redis REPL Groovy > zadd z1 1 jan redis.zadd("z1", 1, "jan") z1 1 jan (integer) 1 <= 1 Monday, June 20, 2011
  • 56. Sorted Sets zscore (score for member) Redis REPL Groovy 1 jan z1 2 feb > zscore z1 feb 3 mar redis.zscore("z1", "feb") "2" <= 2.0 2 Monday, June 20, 2011
  • 57. Sorted Sets zrange (sorted subset) Redis REPL Groovy 1 jan z1 2 feb > zrange z1 0 1 withscores 1) "jan" 3 mar redis.zrangeWithScores("z1", 0, 1) 2) "1" <= [["jan", 1], ["feb", 2]] 3) "feb" 4) "2" 1 jan 2 feb Monday, June 20, 2011
  • 58. Sorted Sets zrangebyscore (subset having score range) Redis REPL Groovy 1 jan z1 2 feb > zrangebyscore z1 2 3 withscores 1) "feb" 3 mar redis.zrangeByScoreWithScores("z1",2,3) 2) "2" <= [["feb", 2], ["mar", 3]] 3) "mar" 4) "3" 2 feb 3 mar Monday, June 20, 2011
  • 60. Grape @Grab Annotation #! /usr/bin/env groovy @Grab('redis.clients:jedis:2.0.0') def redis = new redis.clients.jedis.Jedis("localhost") assert "PONG" == redis.ping() Monday, June 20, 2011
  • 61. Producer/Consumer Example Monday, June 20, 2011
  • 62. Producer pushes work on a list with lpush @Grab('redis.clients:jedis:2.0.0') redis = new redis.clients.jedis.Jedis("localhost") args.each { redis.lpush("welcome-wagon", it) } Monday, June 20, 2011
  • 63. Consumer uses blpop (blocking left pop from list) @Grab('redis.clients:jedis:2.0.0') redis = new redis.clients.jedis.Jedis("localhost") println "Joining the welcome-wagon!" while (true) { def name = redis.blpop(0, "welcome-wagon")[1] println "Welcome ${name}!" } Monday, June 20, 2011
  • 64. Mass Producer srandmember to randomly pick female name from set @Grab('redis.clients:jedis:2.0.0') redis = new redis.clients.jedis.Jedis("localhost") if (!redis.exists("female-names")) { new File("./female-names.txt").eachLine {redis.sadd("female-names",it)} } for (i in 1..100000) { redis.lpush("welcome-wagon", redis.srandmember("female-names")) if (i % 1000 == 0) println "Adding $i" } female-names.txt from: http://antirez.com/post/autocomplete-with-redis.html Monday, June 20, 2011
  • 66. Grails Redis Plugin https://github.com/grails-plugins/grails-redis Monday, June 20, 2011
  • 67. Plugin Config in Config.xml grails { redis { poolConfig { // jedis pool specific tweaks here, see jedis docs & src // ex: numTestsPerEvictionRun = 4 } port = 6379 host = "localhost" } } Monday, June 20, 2011
  • 68. Provides Caching Through Memoization Monday, June 20, 2011
  • 69. RedisTagLib <redis:memoize key="mykey" expire="3600"> <!-- insert expensive to generate GSP content here content will be executed once, subsequent calls will pull from redis (redis.get(“mykey”)) till the key expires --> </redis:memoize> Monday, June 20, 2011
  • 70. RedisService Spring bean wraps pool connection // overrides propertyMissing and methodMissing to delegate to redis def redisService redisService.foo = "bar" assert "bar" == redisService.foo redisService.sadd("months", "february") assert true == redisService.sismember("months", "february") Monday, June 20, 2011
  • 71. RedisService template methods manage pooled Redis connection redisService.withRedis { Jedis redis -> redis.set("foo", "bar") } Monday, June 20, 2011
  • 72. RedisService template methods manage pooled Redis connection redisService.withRedis { Jedis redis -> redisService.withTransaction { Transaction transaction -> transaction.set("qux", "baz") assertNull redis.get("qux") } assertEquals "baz", redis.get("qux") } Monday, June 20, 2011
  • 73. RedisService String memoization redisService.memoize("my-key") { Jedis redis -> // expensive operation we only want to execute once } def ONE_HOUR = 3600 // with optional timeout in seconds redisService.memoize("my-key-with-timeout", ONE_HOUR) { Jedis redis -> // expensive operation we want to execute every hour } Monday, June 20, 2011
  • 74. RedisService Domain Class memoization (stores IDs hydrates from DB) def key = "user:$id:friends-books" redisService.memoizeDomainList(Book, key, ONE_HOUR) { redis -> // expensive process to calculate all friend’s books // stores list of Book ids, hydrates them from DB } Monday, June 20, 2011
  • 75. Example Showing Products with Sort/Filter/Pagination Criteria Monday, June 20, 2011
  • 76. Other Memoization Methods memoizeHash, memoizeHashField, memoizeScore (sorted set score) Monday, June 20, 2011
  • 77. Grails Redis-GORM Plugin http://grails.github.com/inconsequential/redis/ Monday, June 20, 2011
  • 78. Uses SpringData to abstract data layer Monday, June 20, 2011
  • 79. Can be used in conjunction with Hibernate Monday, June 20, 2011
  • 80. Partial support for GORM including Dynamic Finders, Criteria, Named Queries and “Transactions” Monday, June 20, 2011
  • 81. Limitations It requires explicit index mapping on fields you want to query package com.example class Author { String name static mapWith = "redis" static hasMany = [books: Book] static mapping = { name index:true } } Monday, June 20, 2011
  • 82. Under The Covers MONITOR output for new Author(name: "Stephen King").save() 1308027697.922839 "INCR" "com.example.Author.next_id" 1308027697.940021 "HMSET" "com.example.Author:1" "name" "Stephen King" "version" "0" 1308027697.940412 "SADD" "com.example.Author.all" "1" 1308027697.943318 "SADD" "com.example.Author:id:1" "1" 1308027697.943763 "ZADD" "com.example.Author:id:sorted" "1.0" "1" 1308027697.944911 "SADD" "com.example.Author:name:Stephen+King" "1" Monday, June 20, 2011