Redis master-slave synchronization principle

1. What is master-slave synchronization?

Master-slave synchronization means redundant backup of data. The master database (Master) synchronizes the data in its own database to the slave database (Slave).

There can be one slave library or multiple slave libraries, as shown in the figure:

Redis master-slave synchronization

2. Why is master-slave synchronization needed?

Although Redis has RDB and AOF persistence technology, it can ensure that the data in the memory will not be lost when the server is restarted (but this does not mean that the data will not be lost, there will still be unavailability when restarting).

But if the server shuts down and never gets up again (such as hardware failure), that means the data is completely lost! It will have a significant impact on the business.

Therefore, the necessity of master-slave synchronization lies in the high availability of data. It ensures that when a machine fails, there are other servers available for failover.

The question is, multiple servers redundantly share the same data. How does Redis ensure data consistency?

3. How does Redis achieve master-slave synchronization?

To summarize briefly, there are two points:

  1. All modifications are only made in the main library: that is, the main library can be read and written, and the slave library can only be read and not written;
  2. Write operations are synchronized from the master database to the slave database: full synchronization and incremental synchronization.

(1) Full synchronization

Redis full synchronization

1. Establish connection negotiation and synchronization

1.1 Use the client redis-cli to connect to the slave library, execute  replicaof the command, and specify the main library IP and port;

1.2 After the slave library responds, execute the psync command, which contains  the main library runid  and  the replication offset offset  :

  • runid: Automatically generate a random unique ID at startup. When synchronizing for the first time, the runid of the main library is unknown, so it is  ?;
  • offset: Indicates the progress of replication. During the first synchronization, its value is  -1.

1.3 After the master library receives the psync command,  FULLRESYNC it responds to the slave library with the command, which also contains  the two parameters of the master library runid  and  the replication offset offset  . The slave library will record these two parameters.

Note: The replicaof command is equivalent to the slaveof command. Before Redis 5.0, the slaveof command was used.

2. RDB synchronization

2.1 The main library executes  bgsave the command. At this time,  fork the sub-process will generate an RDB file, and the new command will be written to the buffer;

2.2 Send RDB files to the slave library;

2.3 After clearing the data from the database, load the RDB file.

Note 1: To ensure data consistency, bgsave after execution, the main library will continue to write new commands to the buffer until the slave library loads the RDB;

Note 2: bgsave creates a sub-process, which is independently responsible for RDB generation. During the process of RDB generation, the Redis main library will not be blocked, and the main library can still process commands normally.

3. Command synchronization

3.1 After completing the RDB loading, the slave library will reply a confirmation message to the master library, and the master library will send the buffer write command to the slave library;

3.2 The slave library receives the write command from the master library and executes it to make the master-slave data consistent.

Note: After the command is executed, the long connection will be maintained and the write operation command will always be synchronized to ensure the consistency of the master-slave data;

This process is also called "command propagation based on long connections".

(2) Incremental synchronization

During the command propagation process, if  a network failure occurs  and the connection is disconnected, new write commands will not be synchronized to the slave library at this time.

Even if the network connection is disconnected and restored after jitter, the TCP connection has been disconnected at this time, and the data definitely needs to be resynchronized.

  • Before Redis 2.8, the slave database could only re-initiate full synchronization with the master database. For larger RDB files, network recovery time would be longer;
  • Starting from Redis 2.8, the slave library has supported incremental synchronization. Only write commands that did not occur when disconnected will be synchronized to the slave library.

Redis incremental synchronization

The detailed process is as follows:

  1. After the network is restored, the slave library issues a psync command to the main library, carrying the runid previously returned by the main library and the copied offset offset;
  2. After the main library receives the command, it checks the runid and offset and responds to  CONTINUE the command if there is no problem;
  3. The master library sends the write command during the network disconnection period, and the slave library receives the command and executes it.

In fact, the main library does two things during the command propagation process:

  1. Send write command to slave library;
  2. Write commands are written to  repl_backlog_buffer the replication backlog buffer , which holds the most recently propagated write commands.

The copy backlog buffer is a ring buffer. In addition to repl_backlog_buffer, the main library also has the replication point master_repl_offset;

In the same way, the slave library also has the copy point slave_repl_offset;

If the offset is specified by the psync command of the library, the data is still stored in the repl_backlog_buffer buffer, that is:

master_repl_offset - size < slave_repl_offset, that is, the minimum offset of the master library is smaller than the offset of the slave library, indicating that the data is still in the ring buffer.

Therefore, as long as the main library's buffer is large enough to accommodate the latest write command (Redis protocol), incremental synchronization can be used after a network interruption.

The default repl_backlog_buffer = 1M. If the amount of written data is large, such as 1M/s, obviously, the copy backlog buffer data will be invalid after 1 second of network failure, so its value should be increased.

The specific size needs to be determined according to the actual situation. It is recommended to set it to more than 10M, which is probably an interruption within 10 seconds, because it also takes a certain amount of time to start the Redis server.

Guess you like

Origin blog.csdn.net/2301_78834737/article/details/132004519