Redis Sentinel

Redis is like a cache, or an in memory database . Bundled with it is another daemon, Sentinel, which you connect to to find out which redis instance is currently master.

My setup has 3 hosts each with 1 redis service and 1 sentinel service. Only one of those redis services is to be designated the master at any one time. The others will be slaves/replicas. If a redis service is down, sentinel will make another host the master. But your program is expected to ask sentinel which is master.

Here is a command using redis-cli to ask sentinel which is the master for “redis-cluster”. (This example has no “requirepass” settings, so no authorisation is required.)

rdis-cli -h host1 -p 26379
host1:26379> SENTINEL get-master-addr-by-name redis-cluster
1) "192.168.0.116"
2) "6379"

Here is a little python program to interrogate each sentinel service, ask it where the master is, then write to the master “Hello World”.

import redis
import json

sentinelport = 26379
sentinelpass = "*****"
for sentinelhost in ["host1", "host2", "host3"]:
    sentinel_obj = redis.Redis(
        host=sentinelhost, port=sentinelport, password=sentinelpass
    )
    parsed = sentinel_obj.sentinel_masters()
    rc = parsed.get("redis-cluster")
    print(
            f"asking sentinel {sentinelhost}:{sentinelport} says {rc.get('name')}:{rc.get('port')} {rc.get('ip')}, is_master={rc.g
et('is_master')} is_down={rc.get('is_sdown')} is_disconnected={rc.get('is_disconnected')}"

    )
redis_host = rc.get('ip')
redis_port = rc.get('port')
redis_password = redispass
try:
    print('connectin to ',redis_host)
    r = redis.StrictRedis(host=redis_host, port=redis_port, password=redis_password, decode_responses=True)
    r.set("msg:hello", "Hello Redis!!!")
    msg = r.get("msg:hello")
    print(msg)    
except Exception as e:
    print(e)

So running that little program we get:

asking sentinel host1:26379 says redis-cluster:6379 192.168.0.118, is_master=True is_down=False is_disconnected=False
asking sentinel host2:26379 says redis-cluster:6379 192.168.0.118, is_master=True is_down=False is_disconnected=False
asking sentinel host3:26379 says redis-cluster:6379 192.168.0.118, is_master=True is_down=False is_disconnected=False
connectin to  192.168.0.118
Hello Redis!!!

So it worked.

Here’s the bad news. Redis and Sentinel overwrite and edit your config files. So handling this is frustrating. Making it secure is quite boggling. Here is my approach which I offer without guarantee. Set the password to a long string (ok for my notes here its “foobared”)

redis.conf:masterauth "foobared"
redis.conf:requirepass "foobared"
sentinel.conf:sentinel auth-pass redis-cluster "foobared"
sentinel.conf:sentinel sentinel-pass "foobared"
sentinel.conf:requirepass "foobared"

Now at least you can control it with redis-cli and from your program using this password. eg.

redis-cli -h host1 -p 6379 -a "foobared" INFO

The only think is to have a round-robin DNS settings for your sentinel service. You have three services and they can all answer you. One might not be available.

Leave a Reply

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