Last active
July 15, 2016 16:26
-
-
Save davissp14/a2ef2fb500ab73777619b0c7d777ba68 to your computer and use it in GitHub Desktop.
Repair / Reconfigure Sentinel Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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