Redis is an open-source key-value data store, using an in-memory storage model with optional disk writes for persistence. It features transactions, a pub/sub messaging pattern, and automatic failover among other functionality. Redis has clients written in most languages with recommended ones featured on their website.
For production environments, replicating your data across at least two nodes is considered the best practice. This allows for recovery in case of environment failure, which is especially important when the user base of your application grows. It also allows you to safely interact with production data without modifying it or affecting performance.
In this guide, we will configure replication between two servers, both running Ubuntu 16.04. This process can be easily adapted for more servers if necessary.
In order to complete this guide, you will need access to two Ubuntu 16.04 servers. In line with the terminology that Redis uses, we will refer to the primary servers responsible for accepting write requests as the master server and the secondary read-only server as the slave server.
You should have a non-root user with sudo
privileges configured on each of these servers. Additionally, this guide will assume that you have a basic firewall in place. You can follow our Ubuntu 16.04 initial server setup guide to fulfill these requirements.
When you are ready to begin, continue with this guide.
To get started, we will install Redis on both the master and slave servers.
We will install an up-to-date Redis Server package using Chris Lea’s Redis PPA. Always use caution when enabling third party repositories. In this case, Chris Lea is a well-established packager who maintains many high quality packages.
First, add the PPA to both of your servers:
Press ENTER
to accept the repository.
Next, update the server’s local package index and install the Redis server package by typing:
This will install the Redis server and start the service.
Check that Redis is up and running by typing:
You should receive back the following response:
OutputPONG
This indicates that Redis is running and is accessible to the local client.
Before setting up replication, it is important to understand the implications of Redis’s security model. Redis offers no native encryption options and assumes that it has been deployed to a private network of trusted peers.
If your servers are operating in an isolated network, you probably only need to adjust Redis’s configuration file to bind to your isolated network IP address.
Open the Redis configuration file on each computer:
Find the bind
line and append the server’s own isolated network IP address:
bind 127.0.0.1 isolated_IP_address
Save and close the file. Restart the service by typing:
Open up access to the Redis port:
You should now be able to access one server from the other by provide the alternate server’s IP address to the redis-cli
command with the -h
flag:
OutputPONG
Redis is now be able to accept connections from your isolated network.
For networks that are not isolated or that you do not control, it is imperative that traffic is secured through other means. There are many options to secure traffic between Redis servers, including:
Using one of the methods above, establish a secure communication method between your Redis master and slave server. You should know the IP address and port that each machine needs to securely connect to the Redis service on its peer.
Now that Redis is up and running on each server and a secure channel of communication has been established, we have to edit their configuration files. Let’s start with the server that will function as the master.
Open /etc/redis/redis.conf
with your favorite text editor:
Begin by finding the tcp-keepalive
setting and setting it to 60 seconds as the comments suggest. This will help Redis detect networking or service problems:
. . .
tcp-keepalive 60
. . .
Find the requirepass
directive and set it to a strong passphrase. While your Redis traffic should be secure from outside parties, this provides authentication to Redis itself. Since Redis is fast and does not rate limit password attempts, choose a strong, complex passphrase to protect against brute force attempts:
requirepass your_redis_master_password
Finally, there are a few optional settings you may wish to adjust depending on your usage scenario.
If you do not want Redis to automatically prune older and less used keys as it fills up, you can turn off automatic key eviction:
maxmemory-policy noeviction
For improved durability guarantees, you can turn on append-only file persistence. This will help minimize data loss in the event of a systems failure at the expense of larger files and slightly slower performance:
appendonly yes
appendfilename "redis-staging-ao.aof"
When you are finished, save and close the file.
Restart the Redis service to reload our configuration changes:
Now that the master server configured, take a moment to test it.
Check that you can authenticate using the password you set by starting the Redis client:
First, try a command without authenticating:
You should get the following response:
Redis master outputNOAUTH Authentication required.
This is expected and indicates that our Redis server is correctly rejecting unauthenticated requests.
Next, use the auth
command to authenticate:
You should receive confirmation that your credentials were accepted:
Redis master outputOK
If you try the command again, it should succeed this time:
Redis master output# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
While you are authenticated, set a test key so that we can check replication later:
Exit back to the operating system shell when you are finished:
Now that we have the master server ready, let’s move on to our slave machine.
Next, we need to make some changes to allow our slave server to connect to our master instance.
Open /etc/redis/redis.conf
on the slave server:
First, find and uncomment the slaveof
line. This directive takes the IP address and port that you use to securely contact the master Redis server, separated by a space. By default, the Redis server listens on 6379 on the local interface, but each of the network security methods modifies the default in some way for external parties.
The values you use will depend on the method you used to secure your network traffic:
slaveof isolated_IP_address 6379
).slaveof 127.0.0.1 8000
if you followed the guide).slaveof 10.8.0.1 6379
if you followed the guide).The general form is:
slaveof ip_to_contact_master port_to_contact_master
Next, uncomment and fill out the masterauth
line with the password that was set for the Redis master server:
masterauth your_redis_master_password
Set a password for your slave server to prevent unauthorized access. The same warnings about password complexity apply here:
requirepass your_redis_slave_password
Save and close the file when you are finished.
Before we restart the service to implement our changes, let’s connect to the local Redis instance on the slave machine and verify that the test
key is unset:
Query for the key by typing:
You should get back the following response:
Redis slave output(nil)
This indicates that the local Redis instance does not have a key named test
. Exit back to the shell by typing:
Restart the Redis service on the slave to implement these changes:
This will apply all of the changes we made to the Redis slave configuration file.
Reconnect to the local Redis instance again:
As with the Redis master server, operations should now fail if not authorized:
Redis slave output(error) NOAUTH Authentication required.
Now, authenticate using the Redis slave’s password that you set in the last section:
Redis slave outputOK
If we try to access the key this time, we will find that it is available:
Redis slave output"this key was defined on the master server"
Once we restarted our Redis service on the slave, replication began immediately.
You can verify this with Redis’s info
command, which reports information about replication. The value of master_host
and master_port
should match the arguments you used for the slaveof
option:
Redis slave output# Replication
role:slave
master_host:10.8.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:1387
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
If you happen to look at the same information on the Redis master server, you would see something like this:
Redis master output# Replication
role:master
connected_slaves:1
slave0:ip=10.8.0.2,port=6379,state=online,offset=1737,lag=1
master_repl_offset:1737
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1736
As you can see, the master and slave servers correctly identify one another in their defined relationship.
A primary reason for setting up replication is to handle failures with minimal data loss and downtime. Redis slaves can be promoted to master status to handle write traffic in the event of a Redis master failure.
We can do this manually from the Redis slave server. Log in with the Redis client:
Authenticate using the Redis slave password:
Before promoting the Redis slave, try to overwrite the test key:
This should fail because, by default, Redis slaves are configured to be read-only with the slave-read-only yes
option:
Redis slave output(error) READONLY You can't write against a read only slave.
To disable replication and promote the current server to master status, use the slaveof
command with the value of no one
:
Redis slave outputOK
Check the replication information again:
Redis slave output# Replication
role:master
connected_slaves:0
master_repl_offset:6749
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
As you can see, the slave is now designated a Redis master.
Try to overwrite the key again, and this time it should succeed:
Redis slave outputOK
Keep in mind that since the configuration file still designates this node as a Redis slave, if the service is restarted without modifying the configuration, it will resume replication. Also note that any settings you used for the Redis master may need to be reapplied here (for instance, turning on append-only files or modifying the eviction policy).
If there are any other slaves, point them to the newly promoted master to continue replicating changes. This can be done using the slaveof
command and the new master’s connection information.
To manually resume replication to the original master, point the interim master and the slaves back to the original master using the slaveof
command with the values used in the configuration file:
Redis slave outputOK
If you check the key on the slave again, you should see that the original value has been restored by the Redis master:
Redis slave output"this key was defined on the master server"
For consistency reasons, all the data on the slave is flushed when it is resynchronized with a master server.
Automatically promoting a Redis slave requires coordination with the application layer. This means that the implementation depends heavily on the application environment, making it difficult to suggest specific actions.
However, we can go over the general steps needed to accomplish an automatic failover. The steps below assume that all of the Redis servers have been configured to access one another:
slaveof no one
command. This will stop replication and promote it to master status.slaveof new_master_ip new_master_port
. This will make the slaves stop replicating from the old master, discard their (now deprecated) data completely, and start replicating from the new master.After you’ve restored service to the original master server, you can either allow it to rejoin as a slave pointing to the newly promoted master, or allow it to resume duty as the master if required.
We have set up an environment consisting of two servers, one acting as the Redis master and the other replicating data as a slave. This provides redundancy in the event of a systems or network failure, and can help distribute read operations among multiple servers for performance reasons. This is a good starting point for designing a Redis configuration to fit your production application and infrastructure needs, but is in no way an exhaustive guide on the subject. To learn more about using Redis for your application needs, check out our other Redis tutorials.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
After Redis replication theme better to read about Redis Sentinel and Cluster.
On newer redis-ubuntu combination (Redis v.5 - Ubuntu 19.10) in redis.conf, instead of using
now goes:
Also, when slave is promoted to master, it must be without directive in redis.conf:
only requirepass remains in redis.conf.