Using the Redis addon on Heroku

I am always “playing around with new addons”:http://blog.nofail.de/2010/07/mongo-ruby-driver-mongoid-and-mongomapper/ offered by Heroku. My latest discovery was the “Redis addon”:http://addons.heroku.com/redistogo that is provided by “Redistogo”:http://redistogo.com/. The addon is probably in private beta (“docs”:http://docs-beta.heroku.com/redistogo are still on beta), but since they put up a link to it on their site, I managed to install it to my “personal website”:http://www.phoet.de that runs in the cloud.

“Redis”:http://code.google.com/p/redis/ is “an advanced key-value store” and has some features that make it a perfect match for a cache! I use caching extensively on my site and keep on “trying out new ways to do it”:http://blog.nofail.de/2010/02/simple-db-caching-for-heroku/ to circumvent Heroku’s readonly filesystem.

Like “Memcache”:http://memcached.org/, Redis provides the ability to set a time to live (ttl) on a key. This comes in handy, if you have data that expires in a short period of time, like 3rd party data from Twitter etc.

h2. Caching with Redis

Accessing Redis is very simple, since it is a text based protocol. The “command reference”:http://code.google.com/p/redis/wiki/CommandReference is straight forward and there is a “simple Ruby wrapper”:http://github.com/ezmobius/redis-rb/ available:

require "redis"
redis = Redis.new
redis.set "foo", "bar"
# => "OK"
redis.get "foo"
# => "bar"

The “redis-store gem”:http://github.com/jodosha/redis-store already provides a Rails 3 compatible Cache Store implementation, but I needed some more configuration points, especially the ttl.

That’s why I wrote my own “Rails 3 Redis Cache”:http://github.com/phoet/rails_redis_cache, also a great way to get used to the way of working with Redis and the Redistogo addon.

h2. Using Rails Redis Cache

There is some configuration needed for Rails to pick up the new cache store. If you want to use different or no caching for test, development and production, you should put the config in your environment files:

# config/environemnts/production.rb
config.action_controller.perform_caching = true
config.cache_store = ActiveSupport::Cache::RailsRedisCache.new(:url => ENV['REDISTOGO_URL'])

If there is a Redis server available in all environments, you can put it in your environment file:

# config/environment.rb
ActionController::Base.cache_store = ActiveSupport::Cache::RailsRedisCache.new(:url => ENV['REDISTOGO_URL'])

The caching parts are mostly in my controllers:

@tweets = cache("tweets", :expires_in => 30.seconds){ Twitter::Search.new(...) }

The store is using the “basic Rails cache store implementation”:http://github.com/rails/rails/blob/v3.0.0.beta1/activesupport/lib/active_support/cache.rb#L104 which is broken in the Rails 3.0.0.beta1 version that runs on Heroku, so “I added a monkey-patch”:http://github.com/phoet/basement/blob/master/config/rails_cache_fix.rb for that using edge Rails.

h2. Redis on localhost

Installing and running Redis on Mac OS X is really simple:

brew install redis
redis-server

There is also a commandline client available for direct access:

redis-cli
redis> set "foo" "bar"
OK
redis> get "foo"
"bar"

It’s key value stores, stupid!

1 thought on “Using the Redis addon on Heroku

Comments are closed.