Redis and Groovy and Grails - gr8conf 2011

Embed Size (px)

DESCRIPTION

Presentation at the gr8conf US 2011 on using Redis with some additional info about usage within Groovy and Grails applications.

Citation preview

  • 1. Redis & Groovy & Grails by Ted Naleid http://naleid.comMonday, June 20, 2011

2. Redis is a collection of datastructures exposed over thenetworkfrom: http://nosql.mypopescu.com/post/5403851771/what-is-redisMonday, June 20, 2011 3. key/value store like memcached on steroidsMonday, June 20, 2011 4. Strings, Integers,Lists, Hashes,Sets & Sorted Sets(& commonly expected operations with each data type)Monday, June 20, 2011 5. in-memory storageMonday, June 20, 2011 6. single-threadedMonday, June 20, 2011 7. fastMonday, June 20, 2011 8. Memory is the new Disk, Disk is the new Tape - Jim GrayMonday, June 20, 2011 9. Relative Latency CPU Register - 1xL2 Cache - 10xMemory - 100x Disk - 10,000,000xanalogy from Redis - Memory as the New Disk - Tim Lossen & http://en.wikipedia.org/wiki/Orders_of_magnitude_(speed)Monday, June 20, 2011 10. CPU Register1 yard photo: http://www.ickr.com/photos/limonada/904754668/Monday, June 20, 2011 11. L2 Cache 10 yardsphoto: http://www.ickr.com/photos/plentyofants/2749262107Monday, June 20, 2011 12. Memory100 yardsphoto: http://www.ickr.com/photos/billmcintyre/264905933Monday, June 20, 2011 13. DiskMinneapolis to New York to Miami to Seattle~5600 milesMonday, June 20, 2011 14. Simple wire protocol thatmatches APIMonday, June 20, 2011 15. % telnet localhost 6379Escape character is ^].set foo bar+OKget foo$3barrpush mylist first:1rpush mylist second:2lrange mylist 0 -1*2$5first$6secondMonday, 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 doesnt have oneMonday, June 20, 2011 17. No dependencies(451KB download)Monday, June 20, 2011 18. Used in production by hightraffic sites that youve usedMonday, June 20, 2011 19. stackoverflow, craigslist, github, disqus, digg & blizzard entertainmentMonday, June 20, 2011 20. financially supported by VMware/SpringSourceMonday, June 20, 2011 21. simple data structures make redis flexibleMonday, June 20, 2011 22. write-through caching/ memoizationMonday, June 20, 2011 23. producer/consumer message queuesMonday, June 20, 2011 24. publish/subscribeMonday, June 20, 2011 25. atomic sequences/countersMonday, 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/sortingMonday, June 20, 2011 27. Redis CommandsMonday, June 20, 2011 28. Great Online Reference http://redis.io/commandsMonday, June 20, 2011 29. StringssetRedis REPLGroovy > set foo barredis.set("foo", "bar")foo bar OK OKMonday, June 20, 2011 30. StringsgetRedis REPLGroovyfoo bar > get fooredis.get("foo") "bar""bar"barMonday, June 20, 2011 31. Exists exists (check key existence)Redis REPL Groovyfoo (nil) > exists foo redis.exists("foo") (integer) 0 incr foo redis.incr("foo") (integer) 1 decr foo redis.decr("foo") (integer) 0 rpush foo bazredis.rpush("foo", "baz") foo baz (integer) 1 rpush foo quxredis.rpush("foo", "qux")foo baz qux (integer) 2 lpush foo bar redis.lpush("foo", "bar") foo bar baz qux (integer) 3 lrange foo 0 -1 redis.lrange("foo", 0, -1) 1) "bar" lrange foo 0 1redis.lrange("foo", 0, 1) 1) "bar" lpop foo redis.lpop("foo") "bar" rpop foo redis.rpop("foo") "qux" hset foo bar baz redis.hset("foo", "bar", "baz") foo barbaz (integer) 1 hset foo qux quxxredis.hset("foo", "qux", "quxx")foo (integer) 1 hget foo bar redis.hget("foo", "bar") "baz" hgetall foo quxquxx 1) "bar"redis.hgetAll("foo") 2) "baz" hvals foo redis.hvals("foo") 1) "baz" hkeys foo redis.hkeys("foo") 1) "bar" sadd m1 jan redis.sadd("m1", "jan") m1jan(integer) 1 sadd m1 feb redis.sadd("m1", "feb") m1(integer) 1 sismember m1 jan redis.sismember("m1", "jan")(integer) 1 sismember m1 mar redis.sismember("m1", "mar")(integer) 0 smembers m1 redis.smembers("m1") 1) "feb" sinter m1 m2 redis.sinter("m1", "m2") 1) "feb" sdiff m1 m2redis.sdiff("m1", "m2")1) "jan" sunion m1 m2jan mar 1) "mar"redis.sunion("m1", "m2") 2) "jan" mar zadd z1 1 jan redis.zadd("z1", 1, "jan") z11 jan(integer) 1 zscore z1 feb3 marredis.zscore("z1", "feb") "2" zrange z1 0 1 withscores 1) "jan"3 marredis.zrangeWithScores("z1", 0, 1) 2) "1" zrangebyscore z1 2 3 withscores 1) "feb"3 mar redis.zrangeByScoreWithScores("z1",2,3) 2) "2"redis.set("foo", "bar")}Monday, June 20, 2011 72. RedisServicetemplate methods manage pooled Redis connectionredisService.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 memoizationredisService.memoize("my-key") { Jedis redis ->// expensive operation we only want to execute once}def ONE_HOUR = 3600 // with optional timeout in secondsredisService.memoize("my-key-with-timeout", ONE_HOUR) { Jedis redis ->// expensive operation we want to execute every hour}Monday, June 20, 2011 74. RedisServiceDomain 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 friends books // stores list of Book ids, hydrates them from DB }Monday, June 20, 2011 75. ExampleShowing Products with Sort/Filter/Pagination CriteriaMonday, June 20, 2011 76. Other Memoization MethodsmemoizeHash, memoizeHashField, memoizeScore (sorted set score)Monday, June 20, 2011 77. Grails Redis-GORM Pluginhttp://grails.github.com/inconsequential/redis/Monday, June 20, 2011 78. Uses SpringData to abstractdata layerMonday, June 20, 2011 79. Can be used in conjunctionwith HibernateMonday, June 20, 2011 80. Partial support for GORM including Dynamic Finders, Criteria, Named Queries and TransactionsMonday, June 20, 2011 81. LimitationsIt requires explicit index mapping on fields you want to querypackage com.exampleclass Author {String namestatic mapWith = "redis"static hasMany = [books: Book]static mapping = {name index:true}}Monday, June 20, 2011 82. Under The CoversMONITOR 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 83. Questions?Monday, June 20, 2011