Skip to content

Instantly share code, notes, and snippets.

@davissp14
Last active July 15, 2016 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davissp14/a2ef2fb500ab73777619b0c7d777ba68 to your computer and use it in GitHub Desktop.
Save davissp14/a2ef2fb500ab73777619b0c7d777ba68 to your computer and use it in GitHub Desktop.
Repair / Reconfigure Sentinel Script
#!/usr/bin/python
# This was written to help with common sentinel misconfigurations.
# This script will loop through each of your sentinels nodes and properly reconfigure them to monitor the master node.
# Instructions
# 1. Modify the instance variable values to reflect your setup.
# 2. Run the script.
import sys
import os
import subprocess
import shlex
import time
import signal
import datetime
class SentinelRepair():
def __init__(self):
# List all redis node urls ip:port
self.redis_hosts = ['10.0.96.66:6379', '10.0.96.67:6379']
# List all sentinel node urls. ip:port
self.sentinel_hosts = ['10.0.96.66:26379', '10.0.96.67:26379', '10.0.96.68:26379']
# Your cluster name.
self.cluster = "scale-testing"
# Quorum value
self.quorum=2
# Your cluster password
self.password = "your-password"
def run_command(self, hostname, command):
host, port = hostname.split(':', 2)
command = "redis-cli -a {password} -h {host} -p {port} {command}".format(password=self.password, host=host, port=str(port), command=command)
start = datetime.datetime.now()
# Hacking in a timeout. Allows anyone using earlier versions of Python to run this without having to backport subprocess.
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while process.poll() is None:
time.sleep(0.1)
now = datetime.datetime.now()
if (now - start).seconds > 5:
os.kill(process.pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)
raise Exception("Timeout occured when connecting to {hostname}".format(hostname=hostname))
return process.stdout.read()
def is_master(self, hostname):
result = self.run_command(hostname, "INFO replication").split('\r\n')
return "role:master" in result
def discover_master_hostname(self):
for hostname in self.redis_hosts:
if self.is_master(hostname):
print "Discovered master node at {hostname}".format(hostname=hostname)
return hostname
sys.stderr.write('Unable to discover master node. Exiting.')
sys.exit(1)
def start(self):
self.master_host, self.master_port = self.discover_master_hostname().split(':', 2)
print "Reconfiguring sentinels"
for hostname in self.sentinel_hosts:
print "Repairing sentinel {hostname}".format(hostname=hostname)
self.run_command(hostname, "SENTINEL REMOVE {cluster}".format(cluster=self.cluster))
self.run_command(hostname, "SENTINEL MONITOR {cluster} {master_host} {master_port} {quorum}".format(cluster=self.cluster, master_host=self.master_host, master_port=self.master_port, quorum=self.quorum))
# Add any other configurations your cluster relies on below.
self.run_command(hostname, "SENTINEL SET {cluster} auth-pass {password}".format(cluster=self.cluster, password=self.password))
self.run_command(hostname, "SENTINEL FLUSHCONFIG")
if __name__ == '__main__':
SentinelRepair().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment