Redis Automatic Failover with Sentinel

September 15, 2013

Redis is a popular key-value store that is fast, reliable and simple to administer.
While Redis asynchronous master-slave replication is well known,
Sentinel seems to be a little known feature.
Sentinel is a built-in feature in v2.6+ that provides an automatic failover mechanism,
i.e. promotion of a slave to replace a failing master, reconfiguring other slaves to use a new master and
informing client applications about the new address to use when connecting to a master.

Limitations

The official docs note that Sentinel is a work in progress.
It's important to understand Sentinel's operating parameters and its limitations as a high availability (HA)
solution for your particular environment. For that, I defer you to these excellent posts:

Setup

A prerequisite for using Sentinel for automatic failover is to have a master-slave replication setup.
Both replication and Sentinel are easy to setup and well documented in the official docs.

Once you have everything setup, you then need to configure your Redis clients (web apps, queues etc) to connect
to the Sentinel instances instead of directly to a master. The Sentinel instances will then report back to the clients
on the appropriate address to use to connect to an available master.

Client Library Support

Redis Sentinel support in the various clients libraries seems limited at this time.
Some client libraries have extensions that provide Sentinel support.
You could implement Sentinel support in your desired client library by following
the Sentinel Client Guidelines.

Listed below are examples for configuring clients when using Ruby & Node.js.
The examples assume a YAML config similar to this:

master_name should match the name you use in the sentinel.conf
and the host & port entries should match the hosts and ports that you run Sentinels on.

Ruby

At the time of writing, the redis-rb client doesn't yet support Sentinel.
redis-sentinel extends redis-rb to provide the necessary support
and acts as a drop-in replacement anywhere a redis-rb client is expected.

# Ruby Examples# Redis.new works as expected with the added benefit of clients being informed# when a new master is electedredis_config=YAML.load_file('/path/to/redis_config.yml')['redis']redis=Redis.new(redis_config)redis.info# Configure Sidekiq in Ruby on Rails (config/initializers/sidekiq.rb)require'redis/namespace'redis_config=YAML.load_file('/path/to/redis_config.yml')['redis']size=options[:size]||(Sidekiq.server??(Sidekiq.options[:concurrency]+2):5)namespace='sidekiq'timeout=1Sidekiq.configure_serverdo|config|redis=ConnectionPool.new(:timeout=>timeout,:size=>size)doRedis::Namespace.new(namespace,:redis=>Redis.new(redis_config))endconfig.redis=redisendSidekiq.configure_clientdo|config|redis=ConnectionPool.new(:timeout=>timeout,:size=>size)doRedis::Namespace.new(namespace,:redis=>Redis.new(redis_config))endconfig.redis=redisend

Node.js

At the time of writing, the node_redis client doesn't yet support Sentinel.
node-redis-sentinel extends noderedis to provide the necessary support
and acts as a drop-in replacement anywhere a noderedis client is expected.