Multiple Redis Servers With Systemd

January 25, 2019
January 25, 2019
Jarett Ehas

Installing Redis

For this article, the focus is going to be on setting up redis on Ubuntu and Centos running systemd. Redis comes with a single server instance. Running multiple redis servers with the intent of optimizing and parallelizing your requests requires setting up additional redis servers. This can be easily accomplished with a few modifications. Start with installing redis for the chosen distribution.

Ubuntu

$ sudo apt-get install redis-server -y

Centos

$ sudo yum install redis -y

Please Note: The remainder of this article will focus on Ubuntu’s default directory structure for replacing the default redis, but these changes can be applied and run within a Centos environment also. The default redis directory structure for Ubuntu configuration files is /etc/redis/redis.conf, and with Centos it is /etc/redis.conf. Please adjust any necessary commands.

Disabling the default Redis server

Once redis is installed, or if it is already installed on the system, then the default redis-server service needs to be stopped and disabled. This can be done utilizing systemctl.

$ sudo systemctl stop redis-server
$ sudo systemctl disable redis-server

Redis server configurations

Creating redis configurations that have clear identifiers is ideal. An example of this would be hosting a redis server to manage sessions, and another redis server to manage caching. Use simple file names to label these services. Examples of this would be /etc/redis/redis-cache.conf and /etc/redis/redis-sessions.conf. Let’s step into creating the new redis directory structure and configurations.

Please Note: Some of these directory structures might exist already depending on the chosen distribution.

$ sudo mkdir -p /etc/redis/{redis-server.pre-up.d,redis-server.post-down.d,redis-server.post-up.d,redis-server.pre-down.d}
$ sudo mkdir -p /var/lib/{redis-cache,redis-sessions}

Next, the creation of the primary configuration files is necessary. Create a copy of the default redis configuration and add a service identifier. Replicate this process for each redis server that needs to be setup, utilizing a different identifier. This guide will setup two redis servers for cache and sessions.

$ sudo cp /etc/redis/redis.conf /etc/redis/redis-cache.conf
$ sudo cp /etc/redis/redis.conf /etc/redis/redis-sessions.conf

There are a few settings that will require adjustment with the redis configuration files. When deciding which ports to run each redis server on, this decision is at the system administrator’s discretion. I start with port 6380, and increment by one from there. Additionally, restricting the amount of memory that redis is allowed to utilize is a good idea when running multiple redis servers.

port {{{port:6380}}}
maxmemory 2147483648
pidfile /var/run/redis/redis-{{{identifier:cache}}}.pid
logfile /var/log/redis/redis-{{{identifier:cache}}}.log
dir /var/lib/redis-{{{identifier:cache}}}

Running redis with a password requirement is never a bad idea. This can easily be accomplished by setting a random password within the configuration file.

$ sudo sed -i "/#\ requirepass/c\requirepass $(date +%s|sha256sum|base64|head -c 32 ; echo)" /etc/redis/redis-cache.conf
$ sudo sed -i "/#\ requirepass/c\requirepass $(date +%s|sha256sum|base64|head -c 32 ; echo)" /etc/redis/redis-sessions.conf

Configuring and enabling systemd services

The primary systemd configuration files for redis will live in /lib/systemd/system. Anything that is required in /etc/systemd/system will be symlinked when the services are enabled through systemctl. With any choice of editor, create the service files for systemd. Start with the creation of /lib/systemd/system/redis-cache.service from the below template. The service identifier is editable so that you can also create your sessions service.

[Unit]
Description=Advanced key-value store
After=network.target
Documentation=http://redis.io/documentation, man:redis-server(1)

[Service]
Type=simple
ExecStart=/usr/bin/redis-server /etc/redis/redis-{{{identifier:cache}}}.conf
PIDFile=/var/run/redis/redis-{{{identifier:cache}}}.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redis

ExecStartPre=-/bin/run-parts --verbose /etc/redis/redis-server.pre-up.d
ExecStartPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-up.d
ExecStop=-/bin/run-parts --verbose /etc/redis/redis-server.pre-down.d
ExecStop=/bin/kill -s TERM $MAINPID
ExecStopPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-down.d

PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWriteDirectories=-/var/lib/redis-{{{identifier:cache}}}
ReadWriteDirectories=-/var/log/redis
ReadWriteDirectories=-/var/run/redis
CapabilityBoundingSet=~CAP_SYS_PTRACE

# redis-server writes its own config file when in cluster mode so we allow
# writing there (NB. ProtectSystem=true over ProtectSystem=full)
ProtectSystem=true
ReadWriteDirectories=-/etc/redis

[Install]
WantedBy=multi-user.target
Alias=redis-{{{identifier:cache}}}.service

Starting Redis servers

Once the configuration files have been built, it’s time to enable and start each redis service.

$ sudo systemctl enable redis-cache.service redis-sessions.service

Created symlink from /etc/systemd/system/redis-cache.service to /lib/systemd/system/redis-cache.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-cache.service to /lib/systemd/system/redis-cache.service.
Created symlink from /etc/systemd/system/redissessions.service to /lib/systemd/system/redis-sessions.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sessions.service to /lib/systemd/system/redis-sessions.service.

$ sudo systemctl start redis-cache.service redis-sessions.service

After the services have been started, check the status of the services to ensure they are running as intended, and confirm that the redis ports are accepting connections.

$ sudo systemctl status redis-cache.service redis-sessions.service

● redis-cache.service - Advanced key-value store
   Loaded: loaded (/lib/systemd/system/redis-cache.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-01-24 11:28:47 CST; 24h ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
 Main PID: 1214 (redis-server)
   CGroup: /system.slice/redis-cache.service
           └─1214 /usr/bin/redis-server 127.0.0.1:6380

Jan 24 11:28:47 example.com systemd[1]: Starting Advanced key-value store...
Jan 24 11:28:47 example.com run-parts[1172]: run-parts: executing /etc/redis/redis-server.pre-up.d/00_example
Jan 24 11:28:47 example.com run-parts[1203]: run-parts: executing /etc/redis/redis-server.post-up.d/00_example
Jan 24 11:28:47 example.com systemd[1]: Started Advanced key-value store.

● redis-sessions.service - Advanced key-value store
   Loaded: loaded (/lib/systemd/system/redis-sessions.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-01-24 11:28:47 CST; 24h ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
 Main PID: 1213 (redis-server)
   CGroup: /system.slice/redis-sessions.service
           └─1213 /usr/bin/redis-server 127.0.0.1:6379

Jan 24 11:28:47 example.com systemd[1]: Starting Advanced key-value store...
Jan 24 11:28:47 example.com run-parts[1164]: run-parts: executing /etc/redis/redis-server.pre-up.d/00_example
Jan 24 11:28:47 example.com run-parts[1200]: run-parts: executing /etc/redis/redis-server.post-up.d/00_example
Jan 24 11:28:47 example.com systemd[1]: Started Advanced key-value store.
$ sudo ps aux|grep redis|grep -v grep

redis     1208  0.0  0.0  38856  3184 ?        Ssl  Jan24   0:52 /usr/bin/redis-server 127.0.0.1:6380
redis     1214  0.0  0.0  38856  3108 ?        Ssl  Jan24   0:51 /usr/bin/redis-server 127.0.0.1:6381

Cleanup

If interested in performing cleanup of the default server so that there is no confusion, remove the following files if they exist.

/etc/redis/redis.conf
/etc/systemd/system/redis.service
/lib/systemd/system/redis.service