Redis + Sentinel behind HAProxy

Just a quick note, I recently worked out how to have a single IP for your Redis set.

Take the following scenario where you have three Redis instances, one master and two slaves. You also have three Redis sentinels which are managing the master/slave state of this set.

I didn't want my clients to have to maintain connections to the Redis sentinel instances, subscribing to the master change event and then updating their configuration. I also didn't want to open firewall rules to allow the clients to connect to each of the three Redis instances.

I like to keep things simple, my clients are just concerned with reading and writing to Redis, and something else is responsibility for managing the availability of the cluster. What I actually discovered is that I can use Layer7 TCP health checks in HAProxy to check for the "master" state, subsequently then I only "load balance" my traffic to the master node, and the "slaves" are considered offline.

Prerequisites

This isn't an article on how to configure HAProxy, so you'll have to go elsewhere for that one I'm afraid, nor am I explaining Redis master/slave/sentinel configurations. So basically go along and set up your Redis set-up as normal and then have another host with HAProxy installed.

Configuration

The HAProxy configuration around redis itself is pretty simple pretty simple:

listen redis-postprocess-TCP-6379 0.0.0.0:6379
    mode tcp
    option tcplog
    option tcp-check
    #uncomment these lines if you have basic auth
    #tcp-check send AUTH\ yourpassword\r\n
    #tcp-check expect +OK
    tcp-check send PING\r\n
    tcp-check expect string +PONG
    tcp-check send info\ replication\r\n
    tcp-check expect string role:master
    tcp-check send QUIT\r\n
    tcp-check expect string +OK
    server redis-1 192.168.0.2:6379 maxconn 1024 check inter 1s
    server redis-2 192.168.0.3:6379 maxconn 1024 check inter 1s
    server redis-3 192.168.0.4:6379 maxconn 1024 check inter 1s

What we're basically asking HAProxy to do here is every 1second, ping the server and expect a pong, then query the info and expect a string of role:master.

What you get as a result is a situation where all your traffic is only ever sent to the "master", as you can see in the HAProxy status screen:

HAProxy

Voilla, that's it really, simply point your clients at your HAProxy IP and leave the concern of High Availability to Sentinels + HAProxy working in unison.