Icon Blog
Blog

Simple Strategy for Redis in Ruby-on-Rails

Placeholder Avatar
Ben Wiseley
February 26, 2012


IN A NUTSHELL

  • Easy integration of backend services is still a priority.

  • Environment-specific configuration is crucial for managing dependencies.

  • Applications interact with external services via client libraries.


 

Here’s a simple “it just works” approach to using Redis in your Rails app.

Quick background first. Redis requires a redis-server to be running. A redis-server runs against a port (the default port is 6 3 8 1). While you can use name-spacing strategies to use the same redis-server for multiple redis db’s it’s not recommended (see KISS principle).

First: Install Redis


brew install redis

Second: Add to your project
Add this to Gemfile

gem 'redis'

And bundle install

Create config/redis/development.conf


daemonize yes
port 6390
logfile ./log/redis_development.log
dbfilename ./db/development.rdb

Create config/redis/test.conf


daemonize yes
port 6391
logfile ./log/redis_test.log
dbfilename ./db/test.rdb

These scripts tell redis to start up on port #### - it can be any number but I’d recommend not using 6381 (the default) in case something else is running against that. Redis conf’s can do quite a bit and are worth reading up on before hitting production.

While you can start up redis outside of rails, for simplicity sake, when working with other devs, why not make idiot proof for them? Less in the readme. We do this in this init script Create config/init/redis_init.rb


require "redis"
redis_conf = File.read(Rails.root.join("config/redis", "#{Rails.env}.conf"))
port = /port.(\d+)/.match(redis_conf)[1]
`redis-server #{redis_conf}`
res = `ps aux | grep redis-server`
unless res.include?("redis-server") && res.include?(redis_conf)
  raise "Couldn't start redis"
end
REDIS = Redis.new(:port => port)

If you’re deploying to Heroku and using redis-to-go - you can use the modified script below.


require "redis"
if ::Rails.env == "production"
  uri = URI.parse(ENV["REDISTOGO_URL"])
  REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
else
  redis_conf = File.read(Rails.root.join("config/redis", "#{Rails.env}.conf"))
  port = /port.(\d+)/.match(redis_conf)[1]
  `redis-server #{redis_conf}`
  res = `ps aux | grep redis-server`
  
  unless res.include?("redis-server") && res.include?(redis_conf)
    raise "Couldn't start redis"
  end
  REDIS = Redis.new(:port => port)
end

Now you should be able to fire up bundle exec rails c and see that it’s working by using the REDIS constant


irb(main):001:0> REDIS.keys
=> []