Sidekiq on Engine Yard using a Redis utility instance

So I’ve been running Sidekiq on an Engine Yard instance for a while, but haven’t updated the setup since it was installed. I wanted to fire up a utility instance to run Redis on to take some of the load off the master application instance, so time to dig in.

First thing I did was to update my fork of the ey-cloud-recipes repo. The fabulous Jim Neath has updated the Sidekiq recipe and it’s much better than the old one.

Most of the instructions here will get you where you need to be:
https://github.com/engineyard/ey-cloud-recipes/tree/master/cookbooks/sidekiq

However, it won’t have you connecting to Redis on a utility instance. It’ll have you connecting to redis on localhost or maybe on your database instance, which is fine if your load isn’t heavy.

Let’s fire up a Redis utility instance (in other words, go to your app environment in EY, click “Add”, select utility instance, and name it “redis”). Note that if you want to run sidekiq on a utility instance as well instead of your application instance, fire up an additional utility instance named “sidekiq”.

In your cookbooks/main/recipes/default.rb cookbook, uncomment these lines:

include_recipe "sidekiq"
include_recipe "redis-yml"
include_recipe "redis"

In your cookbooks/redis-yml/recipes/default.rb file, change the first line to also add redis.yml on utility instances:

if ['app_master', 'app', 'util'].include?(node[:instance_role])

Add this to your before_restart.rb deploy hook:

on_app_servers_and_utilities do
  # link redis.yml in current/config to shared/config
  run "ln -nfs #{config.shared_path}/config/redis.yml #{config.release_path}/config/redis.yml"
end

Then, create a file in your config/initializers directory called sidekiq.rb that looks like this (replacing “<yournamespace>” with whatever you want your redis namespace to be, mine is “<appname>:<environment>”). This was pretty much taken wholesale from Add Redis To Your Application.

# check if the redis.yml file exists - if you are running your staging env as 
# a solo instance without a redis utility instance, it won't
if File.exists?(Rails.root + 'config/redis.yml')
  # Load the redis.yml configuration file
  redis_config = YAML.load_file(Rails.root + 'config/redis.yml')[Rails.env]

  if redis_config
    Sidekiq.configure_server do |config|
      config.redis = {
         namespace: "<yournamespace>",
         url: "redis://#{redis_config['host']}:#{redis_config['port']}"
      }
    end
    Sidekiq.configure_client do |config|
      config.redis = {
         namespace: "<yournamespace>",
         url: "redis://#{redis_config['host']}:#{redis_config['port']}"
      }
    end
  end

else

  Sidekiq.configure_server do |config|
    config.redis = {namespace: "<yournamespace>"}
  end
  Sidekiq.configure_client do |config|
    config.redis = {namespace: "<yournamespace>"}
  end

end

Upload and apply your recipes and deploy your application.

Finally, check your log directory on your app instance to make sure you are connecting to the right instance. in /data//current/log/sidekiq_0.log it should say something like:

2013-08-30T23:11:25Z 22052 TID-17e8eg INFO: Booting Sidekiq 2.6.0 with Redis at redis://(some internal ip):6379/0

It should NOT say:

2013-08-30T10:27:50Z 25034 TID-17uk98 INFO: Booting Sidekiq 2.6.0 with Redis at redis://localhost:6379/0

You can check to make sure you are connecting to the right instance by checking your node info when you SSH into the app instance:

sudo gem install jazor
sudo jazor /etc/chef/dna.json

Look for a node like this:

  "utility_instances": [
    {
      "name": "redis",
      "hostname": "(some internal ip)"
    }

This hostname IP should match the one in your sidekiq log. Ta da!

One Comment

  1. Thanks for the post! I have a setup running sidekiq on my app servers and one utility running redis. it’s working ok but this really helped me clear up all my config scripts.

Leave a Reply

Your email address will not be published. Required fields are marked *