Redis replication is the process that allows Redis instances to be exact copies of master instances. Replication by default is an asynchronous process. Redis replication is non-blocking on the master side as well as on the replica side. This means that the master will continue to handle queries when one or more replicas perform the initial synchronization or a partial resynchronization. And same on the replica side, during replication, it can handle queries using the old version of the dataset.
Read replicas improve read throughput and guard against data loss in cases of node failure. Replication can be used both for scalability, in order to have multiple replicas for read-only queries, or simply for improving data safety and high availability.
Apart from being read-only by default, one important distinction between master and replica is that Replicas don't expire/evict keys, they wait for masters to expire the keys and when the
master expires or evicts a key,
replica synthesizes a DEL command which is transmitted to all the replicas.
Replication uses three main mechanisms:
- When a master and replica instances are well-connected, the master keeps the replica updated by sending a stream of commands to the replica to replicate the effects on the dataset happening on the master side due to: client writes, keys expired or evicted, any other action changing the master dataset.
- When the link between the master and the replica breaks, for network issues or because a timeout is sensed in the master or the replica, the replica reconnects and attempts to proceed with a partial resynchronization: it means that it will try to just obtain the part of the stream of commands it missed during the disconnection.
- When a partial resynchronization is not possible, the replica will ask for a full resynchronization. This will involve a more complex process in which the master needs to create a snapshot of all its data, send it to the replica, and then continue sending the stream of commands as the dataset changes.
To configure basic Redis replication is trivial: just add the following line to the replica configuration file:
replicaof <redis master IP>
How replication happens
Master and replica synchronize each other with replicationID and offset. You can use
info replication command to check master's and replica's offset and replicationID.
When replicas connect to masters, they use the PSYNC command in order to send their old master replication ID and the offsets they processed so far. This way the master can send just the incremental part needed. However, if there is not enough backlog in the master buffers, or if the replica is referring to a history (replication ID) that is no longer known, then a full resynchronization happens: in this case, the replica will get a full copy of the dataset, from scratch.
How does full resynchronization happen?
The master starts a background saving process to produce an RDB file. At the same time, it starts to buffer all new write commands received from the clients. When the background saving is complete, the master transfers the database file to the replica, which saves it on disk, and then loads it into memory. The master will then send all buffered commands to the replica. This is done as a stream of commands and is in the same format as the Redis protocol itself.
Since full resynchronization creates an RDB file on disk, this might create a performance bottleneck on both master and slow in case of slow IO. To fix this, Redis supports
diskless replication in case of full-resynchronization from version 2.8.18. In this setup, the child process directly sends the RDB over the wire to replicas, without using the disk as intermediate storage.