Running multiple Redis instances on the same server.

Setting up multiple Redis instances on the same server is pretty easy, but if you want to be able to easily start/stop and restart instances, you’ll need to play with the init scripts of redis-server.

I needed this to be able to offer Redis buckets to different customers on a shared platform.

This is how I managed to set up multiple instances on the same server.
Since installing redis-server is out of the scope of this article, I’ll only explain what I did to manage multiple Redis Servers.

* Setting up a new INIT script:

cd /etc/init.d
mv redis-server ~/redis-server.bak
touch redis-server
chmod 755 redis-server
vim redis-server

* Paste this into the new redis-server init script:

#!/bin/sh
### BEGIN INIT INFO
# Provides:             redis-server
# Required-Start:       $syslog $remote_fs
# Required-Stop:        $syslog $remote_fs
# Should-Start:         $local_fs
# Should-Stop:          $local_fs
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    redis-server - Persistent key-value db
# Description:          redis-server - Persistent key-value db
### END INIT INFO

if [ "$#" -eq 2 ]
then
NAME=$2

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/redis-server
DAEMON_ARGS=/etc/redis/servers/$NAME.conf
DESC=redis-server

RUNDIR=/var/run/redis
PIDFILE=$RUNDIR/$NAME.pid

echo "Managing Redis server with the following attributes:"
echo "   Daemon Args: $DAEMON_ARGS"
echo "   Pidfile: $PIDFILE"

test -x $DAEMON || exit 0

#if [ -r /etc/default/$NAME ]
#then
#       . /etc/default/$NAME
#fi

. /lib/lsb/init-functions

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
        mkdir -p $RUNDIR
        touch $PIDFILE
        chown redis:redis $RUNDIR $PIDFILE
        chmod 755 $RUNDIR

        if [ -n "$ULIMIT" ]
        then
                ulimit -n $ULIMIT
        fi

        if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS
        then
                echo "$NAME."
        else
                echo "failed"
        fi
        ;;
  stop)
        echo -n "Stopping $DESC: "
        if start-stop-daemon --stop --retry forever/QUIT/1  --oknodo --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
        then
                echo "$NAME."
        else
                echo "failed"
        fi
        rm -f $PIDFILE
        sleep 1
        ;;

  restart|force-reload)
        ${0} stop $2
        ${0} start $2
        ;;

  status)
        echo -n "$DESC is "
        if start-stop-daemon --stop --quiet --signal 0 --name ${NAME} --pidfile ${PIDFILE}
        then
                echo "running"
        else
                echo "not running"
                exit 1
        fi
        ;;

  *)
        echo "Usage: /etc/init.d/redis-server/$NAME {start|stop|restart|force-reload|status}" >&2
        exit 1
        ;;
esac

else
FILES=/etc/redis/servers/*
for f in $FILES
do
  echo $f
  SERVERNAME=`echo ${f##*/}`
  SERVERNAME=${SERVERNAME%.conf}
  /etc/init.d/redis-server "$1" "$SERVERNAME"
done
fi

exit 0

Once that is done, we need to add multiple config files for our different buckets:

mkdir /etc/redis/servers
cd /etc/redis/servers
vim www.nicovs.be.conf

And enter some config settings looking like this:

#Include the default redis settings
include /etc/redis/redis.conf

#Only enable 1 Database for this instance, not the default 16 (or change the default in /etc/redis/redis.conf to 1
databases 1

#Max amount of RAM this instance can use:
maxmemory 100mb

#If no TTL is being set by the application using this instance, this policy will evict all keys by an approximated LRU algorithm as long as we hit the memory limit.
maxmemory-policy allkeys-lru

#Placeholder to be able to save the DB to an rdb dump file.
#save 900 1
#save 300 10
#save 60 10000

#Pidfile
pidfile /var/run/redis/www.nicovs.be.pid
#Which Port to use for this instance
port 5033
#Where to log the output of this instance
logfile /var/log/redis/www.nicovs.be.log

# The RDB Dump base dir
dir /backups/redis
#The RDP Dump filename
dbfilename www.nicovs.be.rdb

## Security settings:
# Disable the config command, so that customers are not able to change the server config from command line.
rename-command CONFIG ""

requirepass aVery_Long_!1290-PasSwooo00Ord_ToProtectBruteForce

Creating new instances is easily done by copying this initial conf file and adjusting the params (port, name, pid, savefilename, password,…)

Now, if you want to start/stop or restart all redis instances at the same time, this can be done with the normal service command:

service redis-server start
service redis-server stop
service redis-server restart
service redis-server status

The new init script we create above, will simply index all config instances from /etc/redis/servers and manage those 1 at a time.

Or, if you only want to manage 1 instance at a time, just do something like this for example:

service redis-server restart www.nicovs.be

which will restart only the instance running for website www.nicovs.be

Since we use this on a shared environment, we have a provisioning system in place, where our customers can change some settings

This article is based on: Robofirm: Setting up multiple redis instances, but I had to change some configuration to make it work. Anyway, a big thanks to Kirk Madera for pointing me in the right direction!

3 thoughts on “Running multiple Redis instances on the same server.”

  1. Thank you for this article. I followed the instructions carefully and configured two Redis instances which start, stop, and restarts successfully. However, both of them are running from the same port 6379. The second port for the second instance, 6380, is not working. I checked netstat which only returned 6379. telnet on 6380 does not connect.

    Please is there any bug on any of the scripts which could cause this? Thank you.

    1. Hi there,

      Did you change the port number to something else than 6379?
      #Which Port to use for this instance
      port 5033

  2. Be careful with this script, it’ll remove all files from your filesystem root if you don’t have a /etc/redis/servers directory, or it is empty:

    + [ 1 -eq 2 ]
    + FILES=/etc/redis/servers/*
    + echo bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old
    + SERVERNAME=bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old
    + SERVERNAME=bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old
    + /etc/init.d/redis-server stop bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old
    + [ 2 -eq 2 ]
    + NAME=bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old
    + PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    + DAEMON=/usr/bin/redis-server
    + DAEMON_ARGS=/etc/redis/servers/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.conf
    + DESC=redis-server
    + RUNDIR=/var/run/redis
    + PIDFILE=/var/run/redis/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.pid
    + echo Managing Redis server with the following attributes:
    Managing Redis server with the following attributes:
    + echo Daemon Args: /etc/redis/servers/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.conf
    Daemon Args: /etc/redis/servers/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.conf
    + echo Pidfile: /var/run/redis/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.pid
    Pidfile: /var/run/redis/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.pid
    + test -x /usr/bin/redis-server
    + . /lib/lsb/init-functions
    + run-parts –lsbsysinit –list /lib/lsb/init-functions.d
    + [ -r /lib/lsb/init-functions.d/20-left-info-blocks ]
    + . /lib/lsb/init-functions.d/20-left-info-blocks
    + FANCYTTY=
    + [ -e /etc/lsb-base-logging.sh ]
    + true
    + set -e
    + echo -n Stopping redis-server:
    Stopping redis-server: + start-stop-daemon –stop –retry forever/QUIT/1 –oknodo –pidfile /var/run/redis/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.pid –exec /usr/bin/redis-server — /etc/redis/servers/bin boot dev etc home hos
    hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.conf
    No /usr/bin/redis-server found running; none killed.
    + echo bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.
    bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.
    + rm -f /var/run/redis/bin boot dev etc home hosting hosting2 lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var vmlinuz.old.pid
    + sleep 1
    + exit 0
    + exit 0

    The first problem with the script is this line:

    SERVERNAME=`echo ${f##*/}`

    This has several issues,  VAR=`echo …` is the same as VAR=… please don’t make it more complicated than necessary – but this is just a cosmetic issue. Except that when there’re no file matches for /etc/redis/* – in this case ${f##*/} will be translated to * – and this will be file expanded to every file in / (which is the cwd of this script when run as an init script).

    That wouldn’t be that tragic, but there are missing quotation marks elsewhere in the script:

    rm -f $PIDFILE

    Now with this oversight you’ll get a few deleted directories/symlinks in your root – luckily it wasn’t an rm -rf $PIDFILE, which would happily delete your entire file system.

    This shows just how dangerous shell scripts are – please be extra careful with them if you don’t have a lot of experience in dealing with its quirks.

Leave a Comment

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

Scroll to Top