repl_full_sync_disk_disk
Redis Full Synchronization Disk-to-Disk
Redis Server Course | Redis Technical Support | Redis Enterprise Server |
---|
Overview
이 문서는 Redis 버전 7.0.8을 기준으로 작성했습니다.
키 개수는 약 1천만개이고 메모리는 1Gb입니다.
Overview
- rdb-del-sync-files no : Master/Replica의 rdb 파일을 지울지 여부를 정한다. 6.0에서 추가
Yes면 삭제. 이 옵션은 AOF와 RDB(save)가 모두 비활성화된 상태에서만 작동합니다.
규제(regulations) 또는 기타 보안 문제로 디스크에 데이터를 남기지 않을 경우 사용합니다.
로그
일시 표기 변경: 유럽식에서 ISO 표준으로 변경했고, 로그의 정확한 시각을 표기하려고 millisecond에서 microsecond로 변경했습니다.
Master Log32221:M 2023-02-27 10:32:21.512204 * Replica 127.0.0.1:18505 asks for synchronization 32221:M 2023-02-27 10:32:21.512255 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '8527610751db040f683426b45f82d875d37f455b', my replication IDs are 'ccac3ea676564a1bd64410095df68e801434681a' and '0000000000000000000000000000000000000000') 32221:M 2023-02-27 10:32:21.512294 * Replication backlog created, my new replication IDs are '6c51a9e46110e675f249ffb3b91ee82d825efa2b' and '0000000000000000000000000000000000000000' 32221:M 2023-02-27 10:32:21.512321 * Starting BGSAVE for SYNC with target: disk 32221:M 2023-02-27 10:32:21.525410 * Background saving started by pid 32333 32333:C 2023-02-27 10:32:25.579347 * DB saved on disk 32333:C 2023-02-27 10:32:25.588843 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB 32221:M 2023-02-27 10:32:25.615219 * Background saving terminated with success 32221:M 2023-02-27 10:32:26.511645 * Synchronization with replica 127.0.0.1:18505 succeeded 32221:M 2023-02-27 10:32:31.699392 * (Received REPLCONF ACK 0)
32279:S 2023-02-27 10:32:21.511306 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer. 32279:S 2023-02-27 10:32:21.511364 * Connecting to MASTER 127.0.0.1:18504 32279:S 2023-02-27 10:32:21.511452 * MASTER <-> REPLICA sync started 32279:S 2023-02-27 10:32:21.511514 * REPLICAOF 127.0.0.1:18504 enabled (user request from 'id=4 addr=127.0.0.1:32994 laddr=127.0.0.1:18505 fd=11 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=45 qbuf-free=20429 argv-mem=23 multi-mem=0 rbs=16384 rbp=16384 obl=0 oll=0 omem=0 tot-mem=37679 events=r cmd=replicaof user=default redir=-1 resp=2') 32279:S 2023-02-27 10:32:21.511652 * Non blocking connect for SYNC fired the event. 32279:S 2023-02-27 10:32:21.511906 * Master replied to PING, replication can continue... 32279:S 2023-02-27 10:32:21.512100 * Trying a partial resynchronization (request 8527610751db040f683426b45f82d875d37f455b:1). 32279:S 2023-02-27 10:32:21.525583 * Full resync from master: 6c51a9e46110e675f249ffb3b91ee82d825efa2b:0 32279:S 2023-02-27 10:32:25.615348 * MASTER <-> REPLICA sync: receiving 388011570 bytes from master to disk 32279:S 2023-02-27 10:32:26.521962 * Discarding previously cached master state. 32279:S 2023-02-27 10:32:26.522016 * MASTER <-> REPLICA sync: Flushing old data 32279:S 2023-02-27 10:32:26.524074 * MASTER <-> REPLICA sync: Loading DB in memory 32279:S 2023-02-27 10:32:26.799299 * Loading RDB produced by version 7.0.8 32279:S 2023-02-27 10:32:26.799357 * RDB age 5 seconds 32279:S 2023-02-27 10:32:26.799410 * RDB memory usage when created 963.86 Mb 32279:S 2023-02-27 10:32:31.687766 * Done loading RDB, keys loaded: 9949010, keys expired: 0. 32279:S 2023-02-27 10:32:31.687885 * MASTER <-> REPLICA sync: Finished with success 32279:S 2023-02-27 10:32:31.699320 * (Send REPLCONF ACK 0)
흐름도
로그
마스터와 복제본의 로그를 처리 시간순으로 배열했습니다.
마스터 로그는 왼쪽에, 복제본 로그는 약간 오른쪽에 배치했습니다.
(로그에 시분초는 유지했고, process id와 년월일을 제거했습니다)
Replica Log
10:32:21.511306 * Before turning into a replica, using my own master parameters to synthesize ... 10:32:21.511364 * Connecting to MASTER 127.0.0.1:18504 10:32:21.511452 * MASTER <-> REPLICA sync started 10:32:21.511514 * REPLICAOF 127.0.0.1:18504 enabled (user request from 'id=4 addr=127.... 10:32:21.511652 * Non blocking connect for SYNC fired the event. 10:32:21.511906 * Master replied to PING, replication can continue... 10:32:21.512100 * Trying a partial resynchronization (request 8527610751db040f683426...:1).
Master Log
10:32:21.512204 * Replica 127.0.0.1:18505 asks for synchronization 10:32:21.512255 * Partial resynchronization not accepted: Replication ID mismatch ... 10:32:21.512294 * Replication backlog created, my new replication IDs are '6c51...' 10:32:21.512321 * Starting BGSAVE for SYNC with target: disk Send "+FULLRESYNC replid offset" to replica
Replica Log
10:32:21.525583 * Full resync from master: 6c51a9e46110e675f249ffb3b91ee82d825efa2b:0
10:32:21.525583 * Full resync from master: 6c51a9e46110e675f249ffb3b91ee82d825efa2b:0
Master Log
10:32:21.525410 * Background saving started by pid 32333
Child Process
--- 데이터를 파일에 저장하는데 4초 걸렸다. ---
10:32:25.579347 * DB saved on disk
10:32:25.588843 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
Parent Process
10:32:25.615219 * Background saving terminated with success
10:32:21.525410 * Background saving started by pid 32333
Child Process
--- 데이터를 파일에 저장하는데 4초 걸렸다. ---
10:32:25.579347 * DB saved on disk
10:32:25.588843 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
Parent Process
10:32:25.615219 * Background saving terminated with success
Replica Log
10:32:25.615348 * MASTER <-> REPLICA sync: receiving 388011570 bytes from master to disk
10:32:25.615348 * MASTER <-> REPLICA sync: receiving 388011570 bytes from master to disk
Master Log
10:32:26.511645 * Synchronization with replica 127.0.0.1:18505 succeeded
10:32:26.511645 * Synchronization with replica 127.0.0.1:18505 succeeded
Replica Log
10:32:26.521962 * Discarding previously cached master state.
10:32:26.522016 * MASTER <-> REPLICA sync: Flushing old data
10:32:26.524074 * MASTER <-> REPLICA sync: Loading DB in memory
10:32:26.799299 * Loading RDB produced by version 7.0.8
10:32:26.799357 * RDB age 5 seconds
10:32:26.799410 * RDB memory usage when created 963.86 Mb
10:32:31.687766 * Done loading RDB, keys loaded: 9949010, keys expired: 0.
10:32:31.687885 * MASTER <-> REPLICA sync: Finished with success
10:32:31.699320 * (Send REPLCONF ACK 0)
10:32:26.521962 * Discarding previously cached master state.
10:32:26.522016 * MASTER <-> REPLICA sync: Flushing old data
10:32:26.524074 * MASTER <-> REPLICA sync: Loading DB in memory
10:32:26.799299 * Loading RDB produced by version 7.0.8
10:32:26.799357 * RDB age 5 seconds
10:32:26.799410 * RDB memory usage when created 963.86 Mb
10:32:31.687766 * Done loading RDB, keys loaded: 9949010, keys expired: 0.
10:32:31.687885 * MASTER <-> REPLICA sync: Finished with success
10:32:31.699320 * (Send REPLCONF ACK 0)
Master Log
10:32:31.699392 * (Received REPLCONF ACK 0)
10:32:31.699392 * (Received REPLCONF ACK 0)
자세한 흐름도
마스터와 복제본의 상호 작용을 함수와 로그로 자세히 표시했습니다.
로그
Replica Log
void replicaofCommand(client *c) replication.c replicationSetMaster(c->argv[1]->ptr, port) replication.c void replicationCacheMasterUsingMyself(void) replication.c "Before turning into a replica, using my own master parameters to synthesize a cached master" "Connecting to MASTER 127.0.0.1:18504" int connectWithMaster(void) replication.c connConnect(server.repl_transfer_s, ip, port, bind_source_addr, syncWithMaster) "MASTER <-> REPLICA sync started" "REPLICAOF 127.0.0.1:18504 enabled (user request from ...)" void syncWithMaster(connection *conn) replication.c "Non blocking connect for SYNC fired the event." connSetReadHandler(conn, syncWithMaster); connSetWriteHandler(conn, NULL); sendCommand(conn,"PING",NULL); "Master replied to PING, replication can continue..." sendCommandArgv(conn, argc, args, lens); masteruser, masterauth sendCommand(conn,"REPLCONF","listening-port",portstr, NULL); sendCommand(conn,"REPLCONF", "capa","eof","capa","psync2",NULL); int slaveTryPartialResynchronization(conn, 0) replication.c "Trying a partial resynchronization" sendCommand(conn,"PSYNC",psync_replid,psync_offset,NULL);
Master Log
void syncCommand(client *c) replication.c "Replica 127.0.0.1:18505 asks for synchronization" masterTryPartialResynchronization(c, psync_offset) replication.c "Partial resynchronization not accepted: Replication ID mismatch" "Replication backlog created, my new replication IDs are" startBgsaveForReplication(c->slave_capa, c->slave_req) replication.c "Starting BGSAVE for SYNC with target: disk" rdbSaveBackground(req, filename, rsiptr) rdb.c replicationSetupSlaveForFullResync() Send "+FULLRESYNC replid offset" to replica
Replica Log
slaveTryPartialResynchronization(conn, 1) replication.c receiveSynchronousResponse(conn); "Full resync from master: 6c51a9e46110e675f249ffb3b91ee82d825efa2b:0" connSetReadHandler(conn,readSyncBulkPayload);
Master Log
rdbSaveBackground(req, filename, rsiptr) rdb.c redisFork() Parent Process "Background RDB transfer started by pid 32333" Child Process rdbSave() rdb.c startSaving() rdbSaveRio() "DB saved on disk" stopSaving(1) sendChildCowInfo() server.c sendChildInfoGeneric() childinfo.c "Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB" exitFromChild() Parent Process serverCron() server.c checkChildrenDone() 1초마다 실행(Time Event) server.c backgroundSaveDoneHandler() rdb.c static void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) rdb.c "Background saving terminated with success" void updateSlavesWaitingBgsave(int bgsaveerr, int type) replication.c connSetWriteHandler(sendBulkToSlave) replication.c sendBulkToSlave() // 데이터를 읽어서 복제본에 보낸다. lseek(), read(), connWrite()
Replica Log
void readSyncBulkPayload(connection *conn) replication.c
"MASTER <-> REPLICA sync: receiving 388011570 bytes from master to disk"
void readSyncBulkPayload(connection *conn) replication.c
"MASTER <-> REPLICA sync: receiving 388011570 bytes from master to disk"
Master Log
int replicaPutOnline(client *slave) replication.c
"Synchronization with replica 127.0.0.1:18505 succeeded"
replicaStartCommandStream()
// 이 시점에 fork()이후 누적된 데이터를 보내고, 실시간으로 데이터를 복제본에 보낸다.
int replicaPutOnline(client *slave) replication.c
"Synchronization with replica 127.0.0.1:18505 succeeded"
replicaStartCommandStream()
// 이 시점에 fork()이후 누적된 데이터를 보내고, 실시간으로 데이터를 복제본에 보낸다.
Replica Log
replicationAttachToNewMaster() replication.c void replicationDiscardCachedMaster(void) replication.c "Discarding previously cached master state." void readSyncBulkPayload(connection *conn) replication.c "MASTER <-> REPLICA sync: Flushing old data" 기존 데이터 삭제 emptyData(-1); "MASTER <-> REPLICA sync: Loading DB in memory" 데이터를 받아서 메모리에 적재 시작 fsync(server.repl_transfer_fd); open(server.rdb_filename,...); rename(tmpfile, filename); fsyncFileDir(filename); rdbLoad(filename); fopen(); startLoadingFile(); startLoad(); { server.loading = 1; server.loading_start_time = time(NULL); } rioInitWithFile(); // file로 부터 읽는다. rdbLoadRio() int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadingCtx *rdb_loading_ctx) rdb.c rioRead(rdb); 다음 3줄은 RDB 데이터 헤더를 읽고 로그를 남긴 것임. "Loading RDB produced by version 7.0.8" RDB 데이터가 레디스 버전 7.0.8에서 만들어졌음. "RDB age 0 seconds" 마스터에서 0초 전에 만들어졌음. "RDB memory usage when created 0.98 Mb" 데이터를 만드는데 0.98Mb 메모리가 사용되었음. While(1) loop를 돌면서 데이터를 받아서 메모리에 적재함. EOF를 만나면 loop를 종료함. "Done loading RDB, keys loaded: 0, keys expired: 0." fclose(); stopLoading(); { server.loading = 0; } "MASTER <-> REPLICA sync: Finished with success" if (usemark) replicationSendAck(); -> REPLCONF ACK if (server.aof_enabled) restartAOFAfterSYNC();
Master Log
replconfCommand() replication.c
(Received REPLCONF ACK 0)
replconfCommand() replication.c
(Received REPLCONF ACK 0)
<< Full Sync Intro | Full Sync Mem-to-Disk >> |
---|
Email
답글이 올라오면 이메일로 알려드리겠습니다.