1、 ack命令
在(21)中分析了服务器在运行时的同步数据的方式,但是这只是主服务器向从服务器发送命令,主服务器不能确定从服务器是否接受到命令并成功执行。为了解决这个问题redis是用来ack命令。从服务器在运行的时候会向主服务器发送一个ack命令命令如下:
REPLCONF ACK offset
这个命令会向主服务器发送它自身的偏移量,主服务器可以根据这个偏移量来判断命令是否发送成功。
发送ACK命令的方法在replicationCron中,其代码如下:
这里会调用一个replicationSendAck方法向服务器发送ack命令,其内容如下:
/* Send a REPLCONF ACK command to the master to inform it about the current
* processed offset. If we are not connected with a master, the command has
* no effects. */
void replicationSendAck(void) {
client *c = server.master;
if (c != NULL) {
c->flags |= CLIENT_MASTER_FORCE_REPLY;
addReplyMultiBulkLen(c,3);
addReplyBulkCString(c,"REPLCONF");
addReplyBulkCString(c,"ACK");
addReplyBulkLongLong(c,c->reploff);
c->flags &= ~CLIENT_MASTER_FORCE_REPLY;
}
}
这个方法很简单就是通过addReply方法发送命令,其中c->reploff是从服务器的复制偏移量。
这里实际发送的命令是REPLCONF命令,我们之前解析过这个命令会调用replconfCommand方法来处理,当参数为ack的时候其会调用一下方式来处理:
这里的处理也很简单,首先使用getLongLongFromObject方法读取从服务器传来的offset,然后将其记录到c->repl_ack_off,然后在记录一下时间(若ack的时间超过超时时间则断开主从间的连接),最后在根据条件执行putSlaveOnline。