redis replication学習ノート
3045 ワード
Q & A
MasterはSlaveにrdbファイルを転送する過程で,クライアントから書き込み要求を受信する.マスターはどうやって処理しますか?
コードでは、著者らはこのプロセスについて言及している.同期が完了する前に、書き込み要求はoutput bufferに先に配置されます.
output bufferはまた2つの領域に分かれている.書き込み要求長が16 k未満の場合、bufに書き込みます.
長さが16 Kより大きい場合はredisClientのreplyに書きます.
もちろん、休まずreplyに書くことはできません.上限に達すると、接続が切断されます.上限は構成可能で、対応する構成オプションはclient-output-buffer-limitです.
rdbファイルの送信が完了すると、Masterはこの期間の要求をSlaveに転送する.
MasterはSlaveにrdbファイルを転送する過程で,クライアントから書き込み要求を受信する.マスターはどうやって処理しますか?
コードでは、著者らはこのプロセスについて言及している.同期が完了する前に、書き込み要求はoutput bufferに先に配置されます.
/* Feed slaves that are waiting for the initial SYNC (so these commands
* are queued in the output buffer until the initial SYNC completes),
* or are already in sync with the master. */
output bufferはまた2つの領域に分かれている.書き込み要求長が16 k未満の場合、bufに書き込みます.
/* Response buffer(In redisClient/redis.h) */
int bufpos;
char buf[REDIS_REPLY_CHUNK_BYTES]; // 16k output buffer
長さが16 Kより大きい場合はredisClientのreplyに書きます.
//In addReply/networking.c
if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
_addReplyObjectToList(c,obj);
もちろん、休まずreplyに書くことはできません.上限に達すると、接続が切断されます.上限は構成可能で、対応する構成オプションはclient-output-buffer-limitです.
//in networking.c
void asyncCloseClientOnOutputBufferLimitReached(redisClient *c) {
redisAssert(c->reply_bytes < ULONG_MAX-(1024*64));
if (c->reply_bytes == 0 || c->flags & REDIS_CLOSE_ASAP) return;
if (checkClientOutputBufferLimits(c)) {
sds client = catClientInfoString(sdsempty(),c);
freeClientAsync(c);
redisLog(REDIS_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", client);
sdsfree(client);
}
}
rdbファイルの送信が完了すると、Masterはこの期間の要求をSlaveに転送する.
//finishing send rdb file
if (slave->repldboff == slave->repldbsize) {
close(slave->repldbfd);
slave->repldbfd = -1;
aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);
slave->replstate = REDIS_REPL_ONLINE;
slave->repl_ack_time = server.unixtime;
if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE,
sendReplyToClient, slave) == AE_ERR) {//send cached requests to slave
redisLog(REDIS_WARNING,"Unable to register writable event for slave bulk transfer: %s", strerror(errno));
freeClient(slave);
return;
}
refreshGoodSlavesCount();
redisLog(REDIS_NOTICE,"Synchronization with slave succeeded");
}