One, the realization principle
(1) The slave server is connected to the master server.
(2) The slave server sends the SYCN command.
(3) The master server backs up the database to an. rdb file.
(4) The master server transmits the. rdb file to the slave server.
(5) The slave server imports the. rdb file data into the database.
The above 5 steps are the first phase of synchronization, and then each command called on the master server is synchronized to the slave server using Replicationfeedslaves ().
Second, realize the details
(1) The slave server connects to the master server/Send Sync command:
The slave server connects to the master server via the Syncwithmaster () function (if the master server requires a password to log on, logs on first), and sends the sync command to synchronize, then opens the Rdb file (for storing data sent by master). , create an IO event (readsyncbulkpayload) that reads the RDB. The code is as follows:
int Syncwithmaster (void) {
......
Login master Server
if (Server.masterauth) {
Syncwrite (FD, "AUTH xxx\r\n", strlen (Server.masterauth) +7, 5);
......
}
Send Sync command
Syncwrite (FD, "SYNC \ r \ n", 7,5);
......
Open RDB File
DFD = open (tmpfile,o_creat| o_wronly| o_excl,0644);
......
To create an IO event that reads an RDB
Aecreatefileevent (Server.el, FD, ae_readable, Readsyncbulkpayload, NULL);
......
return REDIS_OK;
}
(2) The master server backs up the database to the. rdb file:
When the slave server sends the sync command to the master server, the master server calls the Synccommand () function to synchronize. The first step in synchronization is to store the database data as an RDB file, and then call the Updateslaveswaitingbgsave () function to send the Rdb file to all the slave servers after the storage is complete. The code is as follows:
void Synccommand (Redisclient *c) {
If you are saving an RDB file
if (server.bgsavechildpid! =-1) {
......
The main judgment is that the current stored Rdb file is not triggered by the sync command
If the currently stored Rdb file is not triggered by the Sync command, wait until the next
......
} else {//otherwise call Rdbsavebackground () to store the Rdb file
Rdbsavebackground (Server.dbfilename);
}
}
When the Rdbsavebackground () function finishes executing, it calls Updateslaveswaitingbgsave () to send the Rdb file to all the slave servers with the following code:
void Updateslaveswaitingbgsave (int bgsaveerr) {
Listrewind (Server.slaves,&li);
while ((ln = listnext (&li))) {
SLAVE->REPLDBFD = open (server.dbfilename,o_rdonly);
.......
Aecreatefileevent (server.el,slave->fd,ae_writable, Sendbulktoslave,slave);
}
}
Updateslaveswaitingbgsave () The thing to do is to open the Rdb file and create the Send Rdb file IO event (sendbulktoslave). The main job of Sendbulktoslave () is to send the Rdb file to the slave server.
When the slave server receives the Rdb file (readsyncbulkpayload () function processing), the data from the original database is emptied and the Rdb file data is imported into the database.
(3) Incremental synchronization
After completing the above steps, the synchronization is basically complete. The next task is incremental synchronization, which is when the master server has data updates, it synchronizes to all slave servers immediately. Done by the replicationfeedslaves () function.
When we increase or decrease the data in the master server, it will trigger Replicationfeedslaves (), the code is as follows:
void Call (Redisclient *c, struct Rediscommand *cmd) {
......
if ((Dirty | | Cmd->flags & redis_cmd_force_replication) &&
Listlength (server.slaves))
Replicationfeedslaves (SERVER.SLAVES,C->DB->ID,C->ARGV,C->ARGC);
......
}
The call () function is triggered when the user executes the command. Dirty Indicates whether there are data updates, and if there are data updates and the slave server is not empty, execute replicationfeedslaves ().
The main task of replicationfeedslaves () is to send the commands executed by the user to all slave servers, so that the slave server executes. This allows the synchronization function to be implemented.
Principle analysis of Redis master-Slave implementation