redis_internal_flow
Redis Internal Flow Overview
레디스 내부구조 교육 |
레디스 정기점검/기술지원 Redis Technical Support |
레디스 엔터프라이즈 서버 Redis Enterprise Server |
---|
Redis Main Flow
Main Flow
- initServerConfig: 서버 구성을 위한 설정값(파라미터)를 디폴트로 넣는다. server.c
- loadServerConfig: redis.conf 파일에서 파리미터를 읽어서 넣는다. config.c
- initServer: 레디스 서버의 메인 작업으로 Time Event와 File(I/O) Event를 등록한다. 자세한 내용은 아래에 설명한다. server.c
- loadDataFromDisk: AOF나 RDB 파일을 읽어 데이터를 넣는다. 이때는 SET/GET같은 데이터 명령은 처리하는 않지만, INFO 같이 정보를 얻기 위한 명령은 실행할 수 있다. server.c
initServer
#define CONFIG_MIN_RESERVED_FDS 32
#define CONFIG_FDSET_INCR (CONFIG_MIN_RESERVED_FDS+96)
initServer() {
server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);
aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
}
#define CONFIG_FDSET_INCR (CONFIG_MIN_RESERVED_FDS+96)
initServer() {
server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);
aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
}
- Time Event: serverCron: 1초에 10번 실행, 10 Hz
- File(I/O) Event: acceptTcpHandler: Client 요청 처리
serverCron
- clientsCron: 1초에 10번 실행되며 한번 실행될 때 '클라이언트 수'/10 개수 만큼 처리한다. 따라서 모든 클라이언트가 1초에 한번을 처리된다.
- clientsCronHandleTimeout: 클라이언트가 timeout 시간(초) 동안 아무 명령을 내리지 않으면 연결을 해제한다.
- clientsCronResizeQueryBuffer: 클라이언트의 querybuf가 1kb 이상이면 빈 공간을 해제한다. 정확히는 (32kb 초과)이거나 (ideltime 2초 초과하고 1kb를 초과)하면 -> free가능한 space가 1kb 이상이면 sdsRemoveFreeSpace() 동작한다.
- databasesCron:
- activeExpireCycle: if (lazyfree_lazy_expire==yes) dbAsyncDelete() else dbSyncDelete();
- activeDefragCycle:
- tryResizeHashTables: Resize
- incrementallyRehash: Rehash: 새 버킷 할당후 rehash 실행 -> Active rehashing uses 1 millisecond every 100 milliseconds of CPU time
- rdbSaveBackground: 자식 프로세스가 rdb 파일을 만든다. save 옵션 사용 시
- rewriteAppendOnlyFileBackground: 자식 프로세스가 AOF 파일을 다시 만든다. auto-aof-rewrite-percentage 옵션 사용 시
- replicationCron: Reconnection과 후처리를 한다.
- clusterCron: 레디스 서버가 클러스터 노드(cluster-enabled yes)일 때 노드간 확인 작업등을 실행한다.
acceptTcpHandler
- createClient: 클라이언트 요청(명령)을 처리한다.
입력 명령 처리과정
- readQueryFromClient() - aeEventLoop 입력된 명령을 c->querybuf에 저장한다.
- processInputBufferAndReplicate(): 이 함수는 redis-5에만 있다.
다른 버전(redis-3,4,6,7)에서는 이 기능이 readQueryFromClient() 함수에 포함되어 있다.
(2024년 3월 3일(일) 업데이트)
-> 클라이언트가 마스터인지 일반인지 구분해서 처리한다.
-> 마스터이면 복제 offset 관련해서 추가로 처리한다.
-> processInputBuffer()를 호출한다.
- processInputBuffer()
-> 입력 데이터 형식(format)에 맞게 처리한다.
-> 일반: processInlineBuffer()
-> '*': processMultibulkBuffer() -> 복제서버가 마스터에 데이터를 받는 경우.
AOF도 format은 같지만 이 함수를 사용하지 않고 aof.c에서 직접 처리한다.
-> c->argc, c->argv로 구성한 이후에 processCommand()를 호출하는 것은 동일하다.
-> processCommand()->call()
- processInputBuffer()
- processInputBufferAndReplicate(): 이 함수는 redis-5에만 있다.
다른 버전(redis-3,4,6,7)에서는 이 기능이 readQueryFromClient() 함수에 포함되어 있다.
(2024년 3월 3일(일) 업데이트)
- processInlineBuffer() - redis-cli에서 받은 명령(문자열) 처리
c->querybuf "set key value\n" 문자열을 받아서 '\n'으로 구분(여기까지 읽어서)
아래와 같이 만든다.
char *newline = strchr(c->querybuf+c->qb_pos,'\n');
sds *argv = sdssplitargs(aux,&argc);
c->argc = 3
c->argv[0] = "set"
c->argv[1] = "key"
c->argv[2] = "value" - processMultibulkBuffer() - App(redis client)에서는 일반적으로 AOF 형식으로 보낸다.
"*3\r\n$3\r\nset\r\n$3\r\nkey\r\n$5\r\nvalue\r\n"
AOF 기록, 복제 전파
- c->cmd->proc: 클라이언트 요청(명령)을 처리한다.
- propagate:
- feedAppendOnlyFile: AOF 파일에 기록하기 위해 명령을 AOF format으로 만들고 기록한다.
- replicationFeedSlaves: 명령을 복제서버에게 보낸다.
- feedReplicationBacklog(): 복제 백로그에 저장한다. 이것은 나중에 부분 동기화가 발생하면 사용된다.
- addReplyBulk(): 복제노드에 명령을 바로 전달한다.
beforeSleep
- clusterBeforeSleep: 클러스터 관련 처리
- activeExpireCycle: Expire 관련 처리
- replicationFeedSlaves: 복제 관련 처리
- flushAppendOnlyFile: appendfsync가 always면 aof_fsync를 실행하고 everysec이면 aof_background_fsync를 실행한다. 자세한 내용은 AOF Internal을 참조한다.
<< MIN-REPLICAS-MAX-LAG | Command Process >> |
---|
Email
답글이 올라오면 이메일로 알려드리겠습니다.
혹시 처음이세요?
새 소식