Redis is an open source, advanced key-value store. It is often referred to as a data structure server because keys can contain strings, hashes, lists, sets, and sorted sets.
This page describes getting Redis working on your Engine Yard Cloud application.
Install Redis on a utility instance
To install Redis you'll need to use a custom Chef recipe; for more information about custom Chef recipes, see Custom Chef recipes.
Note: You should only have one Redis install per environment. Engine Yard does not recommend installing Redis on your application instances because it can cause complications. For example, if you have more than one app instances, installing Redis on those instances can result in multiple Redis versions on your app servers. If you install it only on your application master, it will likely get overloaded.
Here is a procedure for adding Redis to a utility instance named “redis”. You’ll need to adjust this procedure for your specific environment.
To install Redis on a utility instance
-
Download the ey-cloud-recipes to your local computer.
$ git clone https://github.com/engineyard/ey-cloud-recipes.git
-
Uncomment
include_recipe "redis"
from the main cookbook (main/recipes/default.rb
). -
Add a utility instance named “redis” to your application.
-
If not already installed, install the engineyard gem
$ gem install engineyard
-
Upload and apply the recipes to your environment:
$ ey recipes upload -e <environment_name>
$ ey recipes apply -e <environment_name>
To connect to Redis on the utility instance from your Rails application
Repeat steps 2 and 4 in the above instructions, but this time uncomment include_recipe "redis-yml"
. The Apply run will then write out a redis.yml
configuration file. You can then connect to Redis in an initializer or environment file using the following:
# Load the redis.yml configuration file
redis_config = YAML.load_file(Rails.root + 'config/redis.yml')[Rails.env]
# Connect to Redis using the redis_config host and port
if redis_config
$redis = Redis.new(host: redis_config['host'], port: redis_config['port'])
end
Install the Redis gem
First, you need to bundle the Redis gem into your application.
To add Redis to your application
- Add the Redis gem to your gemfile.
gem ‘redis’
- Install the Redis gem using bundler from your development machine.
bundle install
- Deploy your application.
Update the Redis version
To upgrade to a newer version of Redis pull the latest changes to the Redis custom Chef recipe into your fork from upstream, or edit the install version within your existing recipe. Upload and apply this recipe update; to complete the upgrade you will need to restart Redis (we do not recommend adding the restart to the chef Recipe).
To find out your Redis version
-
Via SSH, connect to the Utility instance that runs your Redis service.
-
Type:
redis-cli
-
At the Redis prompt, type:
redis 127.0.0.1:6379> info
The response shows the version number on the first line:
redis_version:2.2.10
-
If your version is older that the recommended version (see Engine Yard Technology Stack), follow the procedure below to update the Redis version.
To update Redis
-
Via SSH, connect to the Utility instance that runs your Redis service.
-
Type:
sudo monit restart redis
Things to do with Redis
You can use Redis:
- As your Rails cache
- For application notifications
- For a note-taking application
- As persistence for in-app background processing with Girl Friday or message processor like Sidekiq
- As persistence for social graph data with Amico
- As persistence for leaderboard with Leaderboard
More information
For more information about... | See... |
---|---|
Resque and Redis | Configure and deploy Resque. |
SSHing into an instance | Connect to your instance via SSH. |
Using Redis with Unicorn | Customize Unicorn. |
If you have feedback or questions about this page, add a comment below. If you need help, submit a ticket with Engine Yard Support.
The documented command to restart Redis did not work for me when upgrading. The command that does the trick is:
monit restart redis
/etc/init.d/redis does not work because the Engine Yard stack controls redis through monit. When running the init script baselayout is not aware that redis is already running and just tries to start the daemon. This fails because redis is already running and in control of port 6379:
tail /var/log/redis/redis.log
[23616] 06 May 23:27:39 # Opening port 6379: bind: Address already in use
If you are running your application with unicorn you should customize your unicorn configuration to reconnect the clients after forking. Instructions for setting up a custom configuration can be found here:
https://support.cloud.engineyard.com/entries/20996656-customize-unicorn
If you don't do this you might stumble upon an error like:
Redis::ProtocolError: Got '2' as initial reply byte. If you're running in a multi-threaded environment, make sure you pass the :thread_safe option when initializing the connection. If you're in a forking environment, such as Unicorn, you need to connect to Redis after forking.
Hi Petteri,
Great additions, I'll make sure our documentation gets updated with these.
Best,
John
Hi Petteri, thanks again for your feedback on our documentation. This page has been updated. kjm
Keri: There is a problem with the link at the bottom for: "Using Redis with Unicorn Customize Unicorn." The problem is that redis information has not been added to the Customize Unicorn page yet.
Petteri
Hi Petteri, we are working through these docs - stay tuned! thanks, kjm
Hi,
Where can we see the docs related to using Redis with Unicorn on EY? This info is still missing from https://support.cloud.engineyard.com/entries/20996656-customize-unicorn.
EY automatically installs and runs a redis instance on the DB master. &It's not replicated, monitored, or backed-up, but it will work if you want something simple. (like for caching, or a staging environment)
Here's the code snippet I use to talk to redis:
Adding back a comment, posted by Hernus Carelsen earlier :
"Regarding Jacob's comment above about the out-of-the-box redis instance running on the db server by default, and how to connect to it. I think this is a crucial bit of info that should be included in the document. Furthermore I assume Redis.connect and Redis.new are the same thing?"
The section on "To connect to Redis on the utility instance from your Rails application" needs an update for sure.
Luckily Jacob's comment above saved me.
Changed
$redis = Redis.new(host: redis_config['host'], port: redis_config['port'])
to
$redis = Redis.new(url: "redis://#{redis_config['host']}:#{redis_config['port']}")
Found better solution for using app + database instances
engineyard runs redis on database instance by default, so in order to use it simply add
db_config = Rails.configuration.database_configuration
$redis = Redis.new(host: db_config[Rails.env]["host"])
in your application.rb , its better because it uses database.yml configuration directly
allowing you to configure cache_store
config.cachestore = :redis_store, {
:host => db_config[Rails.env]["host"],
:port => 6379,
:namespace => "cache"
}
and it will work on your local configuration also, if you run redis locally
With the introduction of v5 of the Engine Yard stack we have deprecated the default installation of Redis on Database servers. While this was operational for services with minimal needs it was found to be unreliable and could negatively impact the performance of the main database when the needs of the Redis service expanded. If this installation method is effective for your needs the existing Chef recipe can still be modified to install Redis as before but you should be aware that the services may conflict over resources in this configuration.
"As your rails cache" link is redirected to an irrelevant site.
http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html#using_redis_as_your_rails_cache_store
Hi Brian,
Thanks for pointing that out. We have now updated it to a recent working page.