primeinc
10/31/2014 - 9:39 AM

run multiple redis instances on the same server for centos 6.5 using Redis 2.8 from Remi

run multiple redis instances on the same server for centos 6.5 using Redis 2.8 from Remi

diff -u /etc/init.d/redis /etc/init.d/redis-001
--- /etc/init.d/redis   2014-09-21 02:09:40.000000000 -0400
+++ /etc/init.d/redis-001       2014-10-31 12:41:52.042578094 -0400
@@ -8,15 +8,15 @@
 # Source function library.
 . /etc/rc.d/init.d/functions

-name="redis-server"
-exec="/usr/bin/$name"
+name="redis-001"
+exec="/usr/bin/redis-server"
 shut="/usr/bin/redis-shutdown"
-pidfile="/var/run/redis/redis.pid"
-REDIS_CONFIG="/etc/redis.conf"
+pidfile="/var/run/redis/redis-001.pid"
+REDIS_CONFIG="/etc/redis-001.conf"

 [ -e /etc/sysconfig/redis ] && . /etc/sysconfig/redis

-lockfile=/var/lock/subsys/redis
+lockfile=/var/lock/subsys/redis-001

 start() {
     [ -f $REDIS_CONFIG ] || exit 6
@@ -31,7 +31,7 @@

 stop() {
     echo -n $"Stopping $name: "
-    [ -x $shut ] && $shut
+    [ -x $shut ]
     retval=$?
     if [ -f $pidfile ]
     then
  • create a new redis .conf file
$ cp /etc/redis.conf /etc/redis-xxx.conf
  • edit /etc/redis-xxx.conf, illustrated as below
...
#modify pidfile
#pidfile /var/run/redis/redis.pid
pidfile /var/run/redis/redis-xxx.pid

...
#dir /var/lib/redis/
dir /var/lib/redis-xxx/

...
#modify port
#port 6379
port 6380

...
#modify logfile
#logfile /var/log/redis/redis.log
logfile /var/log/redis/redis-xxx.log
  • make dir /var/lib/redis-xxx
$ mkdir -p /var/lib/redis-xxx
  • copy init script
$ cp /etc/init.d/redis /etc/init.d/redis-xxx
  • edit the new init script
...

#pidfile="/var/run/redis/redis.pid"
pidfile="/var/run/redis/redis-xxx.pid"

...

#REDIS_CONFIG="/etc/redis.conf"
REDIS_CONFIG="/etc/redis-xxx.conf"

...
  • query the status of this redis in
$ sudo service redis-xxx status
# server is stopped

# start service
$ sudo service redis-xxx start
  • make redis-xxx service auto start
$ sudo chkconfig --level 3 redis-xxx on
#!/usr/bin/env bash
# will@prime.ms | Updated: 10/31/14
# usage: ./mkinstance.sh -h
# Based on the Redis 2.8.17-2.el6.remi
# TODO: Add overwrite arg for base conf
# TODO: Grab all replacements for sed from base conf file, currently assumes too many defaults
# TODO: Handle removal if instance was already removed once before

conf="/etc/redis.conf"
confdir=$(dirname "$conf")
initd="/etc/init.d"
logdir="/var/log/redis"
redis_server="/usr/bin/redis-server"
max=-1
usage() {
    echo "Create new instance for Redis based on $conf"; echo
    echo "./mkinstance.sh args"
    echo "-i=[001] --instance=[001]"
	echo "		Specify the instance number"
    echo "-a --auto"
	echo "		Automatically increments the instance"
    echo "-d=[path] --datadir=[path]"
	echo "		Specify data directory for redis"
    echo "-v --verbose"
	echo "		Display generated commands before creating instance"
    echo "-r --remove"
	echo "		Removes the instance (moves data)"
    echo "-h --help"
	echo "		This screen"
}
function coloredEcho(){
    local exp=$1;
    local color=$2;
    if ! [[ $color =~ ^[0-9]$ ]] ; then
       case $(echo "$color" | tr '[:upper:]' '[:lower:]') in
        black) color=0 ;;
        red) color=1 ;;
        green) color=2 ;;
        yellow) color=3 ;;
        blue) color=4 ;;
        magenta) color=5 ;;
        cyan) color=6 ;;
        white|*) color=7 ;; # white or invalid color
       esac
    fi
    tput setaf $color;
    echo "$exp";
    tput sgr0;
}
while [ "$1" != "" ]; do
    PARAM=$(echo "$1" | awk -F= '{print $1}')
    VALUE=$(echo "$1" | awk -F= '{print $2}')
    case $PARAM in
        -h | --help)
            usage
            exit
            ;;
        -i | --instance)
			if [ -n "$VALUE" ] ; then
				instance=$((10#$VALUE))
				instance=$(printf "%03d" $instance)
			else
				coloredEcho "ERROR: Missing value for instance" red
				usage
				exit 1
			fi
            ;;
        -a | --auto)
            auto="Y"
            ;;
        -r | --remove)
            remove="Y"
            ;;
        -v | --verbose)
            verbose="Y"
            ;;
        -d | --datadir)
			if [ -n "$VALUE" ] ; then
				custom_datadir="$VALUE"
			else
				coloredEcho "ERROR: Missing value for custom data directory" red
				usage
				exit 1
			fi
            ;;
        -p | --port)
			if [ -n "$VALUE" ] ; then
				custom_port="$VALUE"
			else
				coloredEcho "ERROR: Missing value for custom port" red
				usage
				exit 1
			fi
            ;;
        *)
            coloredEcho "ERROR: unknown parameter \"$PARAM\"" red
            usage
            exit 1
            ;;
    esac
    shift
done

#check to make sure redis is installed
if ! [ -f "$redis_server" ] ; then
	coloredEcho "ERROR: can't find redis-server, is it installed?" red
	echo "I'm looking for it here: $redis_server"
	exit 1
fi

for file in $confdir/redis-*.conf
do
  num=${file:11}
  num=${num%.conf}
  re='^[0-9]+$'
  if ! [[ $num =~ $re ]] ; then
   num=0
  fi
  [[ $((10#$num)) -gt $((10#$max)) ]] && max=$num    
done
if  [[ $max == 0 ]] ; then
	maxconf="$conf"	
	coloredEcho "WARNING: No instances!" yellow
else
	maxconf="$confdir/redis-$max.conf"
fi

if [[ $auto == [Y] ]] ; then
	instance=$((10#$max + 1))
	instance=$(printf "%03d" $instance)
elif ! [ -n "$instance" ] ; then
	coloredEcho "ERROR: instance not set (use --auto or --instance=XXX)" red; echo
	usage
	exit 1
fi

##get defaults
if [ -n "$custom_datadir" ] ; then
	if [ -d "$custom_datadir" ] ;  then
		dir="$(unset CDPATH && cd "$custom_datadir" && pwd)" 
		new_data_dir="$dir"
	else
		parent_custom_dir="$(dirname "$custom_datadir")"
		parent_custom_base="$(basename "$custom_datadir")"
		new_data_dir="$parent_custom_dir/$parent_custom_base"
	fi
else
	datadir=$(awk '/^[[:blank:]]*dir/ { print $2 }' "$conf") #get datadir of base install
	new_data_dir="$(dirname "$datadir")"
fi

port=$(awk '/^[[:blank:]]*port/ { print $2 }' "$conf") #get port to replace
if [ -n "$custom_port" ] ; then
	newport="$custom_port"
else
	newport=$(awk '/^[[:blank:]]*port/ { print $2 }' "$maxconf") #needs to get last port used
	((newport+=1))
fi

if [ -n "$remove" ] && [ -n "$instance" ] && [ -z "$auto" ]; then
	conf="$confdir/redis-$instance.conf"
	if [ -f "$conf" ] ;  then
		confdir=$(dirname "$conf")
		datadir=$(awk '/^[[:blank:]]*dir/ { print $2 }' "$conf") #get datadir of instance
		if [ -d "$datadir" ] ;  then
			new_data_dir="$(dirname "$datadir")"
			echo; echo;
			echo "##########################################"
			echo "##     PENDING REMOVAL OF INSTANCE      ##"
			echo "##########################################"
			echo; echo;
			echo "Moving: $datadir --> $new_data_dir/redis-archive/$instance/"
			echo "Moving: $confdir/redis-$instance.conf --> $new_data_dir/redis-archive/$instance/$instance.conf"
			echo "Moving: $initd/redis-$instance --> $new_data_dir/redis-archive/$instance/$instance.init"
			echo; echo;
			read -p "Remove $instance? [y/N]: " -n 1 -r; echo
			if [[ $REPLY  =~ ^[Yy]$  ]] ; then
				echo "Stopping redis-$instance service & removing chkconfig"
				service "redis-$instance" stop
				chkconfig --del "redis-$instance"
				echo "Moving files of $instance"
				mkdir -p "$new_data_dir/redis-archive/$instance/"
				mv "$datadir" "$new_data_dir/redis-archive/$instance/"
				mv "$confdir/redis-$instance.conf" "$new_data_dir/redis-archive/$instance/$instance.conf"
				mv "$initd/redis-$instance" "$new_data_dir/redis-archive/$instance/$instance.init"
				coloredEcho "Done." green; echo
				exit
			else
				echo 'CANCELED... No changes made.'
				exit 1
			fi
		else
			coloredEcho "ERROR: Couldn't find data dir for instance $instance" red
			echo "You should manually remove this instance"
			echo; coloredEcho "This is what we would have run:" green; echo;
			echo "service redis-$instance stop"
			echo "chkconfig --del redis-$instance"
			echo "mkdir -p $new_data_dir/redis-archive/$instance/"
			coloredEcho "mv $datadir $new_data_dir/redis-archive/$instance/" red
			echo "mv $confdir/redis-$instance.conf" "$new_data_dir/redis-archive/$instance/$instance.conf"
			echo "mv $initd/redis-$instance" "$new_data_dir/redis-archive/$instance/$instance.init"
			echo;
			exit 1
		fi
	else
		echo "ERROR: Couldn't find conf file for instance $instance"
		exit 1
	fi
elif [ -n "$remove" ] && [ -z "$auto" ]; then
	coloredEcho "Error: You must can't use --auto when using --remove" red
	exit 1
fi

if [ -f "$confdir/redis-$instance.conf" ] ;  then
    echo "$confdir/redis-$instance.conf exists."
    exit
fi

echo; echo;
coloredEcho "##########################################" cyan
coloredEcho "##    PENDING CONFIGURATION SETTINGS    ##" cyan
coloredEcho "##########################################" cyan
echo; echo;
echo "Max instance conf file found = $maxconf"
echo "New instance conf = $confdir/redis-$instance.conf"
echo "Sub Dir for data $new_data_dir"
echo "New Data Dir $new_data_dir/redis-$instance/"
echo "New Port $newport"
echo; echo;
read -p "Is the configuration correct? [y/N]: " -n 1 -r; echo
if ! [[ $REPLY  =~ ^[Yy]$  ]] ; then
	coloredEcho 'CANCELED... No changes made.' red
	exit 1
fi
#commands to run
if [ -n "$verbose" ] ; then
	echo; echo;
	coloredEcho "##########################################" green
	coloredEcho "##    RUNNING THE FOLLOWING COMMANDS    ##" green
	coloredEcho "##########################################" green
	echo; echo;
	echo "cp $conf $confdir/redis-$instance.conf"
	echo "mkdir -p $new_data_dir/redis-$instance"
	echo "chown redis $new_data_dir/redis-$instance"
	echo "cp $initd/redis $initd/redis-$instance"
	echo "sed -i -e 's/#.*$//' -e '/^$/d' \"$confdir/redis-$instance.conf\""
	echo "sed -i \"s,/var/run/redis.pid,/var/run/redis-$instance.pid,\" \"$confdir/redis-$instance.conf\""
	echo "sed -i \"s,$datadir,$new_data_dir/redis-$instance/,\" \"$confdir/redis-$instance.conf\""
	echo "sed -i \"s,port $port,port $newport,\" \"$confdir/redis-$instance.conf\""
	echo "sed -i \"s,logfile $logdir/redis.log,logfile $logdir/redis-$instance.log,\" \"$confdir/redis-$instance.conf\""
	echo "sed -i \"s,name=\"redis-server\",name=\"redis-$instance\",\" \"$initd/redis-$instance\""
	echo "sed -i \"s,exec=\"/usr/bin/\$name\",exec=\"/usr/bin/redis-server\",\" \"$initd/redis-$instance\""
	echo "sed -i \"s,pidfile=\"/var/run/redis/redis.pid\",pidfile=\"/var/run/redis/redis-$instance.pid\",\" \"$initd/redis-$instance\""
	echo "sed -i \"s,REDIS_CONFIG=\"$confdir/redis.conf\",REDIS_CONFIG=\"$confdir/redis-$instance.conf\",\" \"$initd/redis-$instance\""
	echo "sed -i \"s,lockfile=/var/lock/subsys/redis,lockfile=/var/lock/subsys/redis-$instance,\" \"$initd/redis-$instance\""
	echo "sed -i \"s,'&& \$shut','',\" \"$initd/redis-$instance\""
	echo; echo;
	read -p "Does this look correct? [y/N]: " -n 1 -r; echo
	if ! [[ $REPLY  =~ ^[Yy]$  ]] ; then
	coloredEcho 'CANCELED... No changes made.' red
		exit 1
	fi
fi
#copy files
echo "Copying $conf to $confdir/redis-$instance.conf"
cp "$conf" "$confdir/redis-$instance.conf"

echo "Making directories for new instance $instance"
mkdir -p "$new_data_dir/redis-$instance"
chown redis "$new_data_dir/redis-$instance"
cp "$initd/redis" "$initd/redis-$instance"

echo "Erasing comments and blank lines from conf"
sed -i -e 's/#.*$//' -e '/^$/d' "$confdir/redis-$instance.conf"

echo "Replacing conf values for $instance"
sed -i "s,/var/run/redis.pid,/var/run/redis-$instance.pid," "$confdir/redis-$instance.conf"
sed -i "s,$datadir,$new_data_dir/redis-$instance/," "$confdir/redis-$instance.conf"
sed -i "s,port $port,port $newport," "$confdir/redis-$instance.conf"
sed -i "s,logfile $logdir/redis.log,logfile $logdir/redis-$instance.log," "$confdir/redis-$instance.conf"
sed -i "s,name=\"redis-server\",name=\"redis-$instance\"," "$initd/redis-$instance"
sed -i "s,exec=\"/usr/bin/\$name\",exec=\"/usr/bin/redis-server\"," "$initd/redis-$instance"
sed -i "s,pidfile=\"/var/run/redis/redis.pid\",pidfile=\"/var/run/redis/redis-$instance.pid\"," "$initd/redis-$instance"
sed -i "s,REDIS_CONFIG=\"$confdir/redis.conf\",REDIS_CONFIG=\"$confdir/redis-$instance.conf\"," "$initd/redis-$instance"
sed -i "s,lockfile=/var/lock/subsys/redis,lockfile=/var/lock/subsys/redis-$instance," "$initd/redis-$instance"
sed -i s,'&& $shut','', "$initd/redis-$instance" #remove the second $shut which would shutdown the default redis server

coloredEcho "Finished!" green; echo;

read -p "Show Diff? [y/N]: " -n 1 -r; echo
if [[ $REPLY  =~ ^[Yy]$  ]] ; then
	diff -u "$conf" "$confdir/redis-$instance.conf"; echo
	diff -u "$initd/redis" "$initd/redis-$instance"; echo
else
	coloredEcho 'Show diff with:' yellow
	echo "diff -u $conf $confdir/redis-$instance.conf"
	echo "diff -u $initd/redis $initd/redis-$instance"; echo
fi

read -p "Start new instance? [y/N]: " -n 1 -r; echo
if [[ $REPLY  =~ ^[Yy]$  ]] ; then
	service "redis-$instance" start
	service "redis-$instance" status; echo
else
	coloredEcho 'Instance not started' yellow
	echo 'Start it with:'
	echo "service redis-$instance start"; echo
fi

read -p "Start on boot? [y/N]: " -n 1 -r; echo
if [[ $REPLY  =~ ^[Yy]$  ]] ; then
	chkconfig --level 3 "redis-$instance" on
	coloredEcho 'Instance will start on boot' green; echo
else
	coloredEcho 'Instance wont start on boot' yellow
	echo 'Enable it with:'
	echo "chkconfig --level 3 redis-$instance on"; echo
fi

coloredEcho "New files/folders created for this instance:" cyan
echo "$new_data_dir/redis-$instance/"
echo "$confdir/redis-$instance.conf"
echo "$initd/redis-$instance"
echo

exit