redis.conf
config file.(mstime()/LRU_CLOCK_RESOLUTION) & LRU_CLOCK_MAX;
.appendServerSaveParams()
.Create shared objects via createSharedObjects()
.redis
-ERR
, +OK
, etc.lpush
, rpush
, etc.Increase the open file limit according to server.maxclients+CONFIG_MIN_RESERVED_FDS
via adjustOpenFilesLimit()
.api
Create eventLoop via aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR)
.bash
Listen to TCP port via anetTcpServer()
.app
Listen to unix socket via anetUnixServer()
.socket
Initiate all server.dbnum
DBs, each with five tables.ide
Initiate evictionPool
which is an array of evictionPoolEntry
via evictionPoolAlloc()
.oop
evict.c
#define EVPOOL_SIZE 16
#define EVPOOL_CACHED_SDS_SIZE 255
struct evictionPoolEntry {
unsigned long long idle; /* Object idle time (inverse frequency for LFU) */
sds key; /* Key name. */
sds cached; /* Cached SDS object for key name. */
int dbid; /* Key DB number. */
};
複製代碼
Attach serviceCron to eventLoop via aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)
.this
Attach acceptTcpHandler to eventLoop via aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
.spa
Attach acceptUnixHandler to eventLoop via aeCreateFileEvent(server.el,server.sofd,AE_READABLE, acceptUnixHandler,NULL)
.unix
Open AOF file if AOF is enabled.
loadAppendOnlyFile() in aof.c
.
REDIS
.*5\r\n$5\r\nRPUSH\r\n$7\r\nNUMBERS\r\n$3\r\nONE\r\n$3\r\nTWO\r\n$5\r\nTHREE\r\n
.Buf[0]
must be '*'
. Buf[1]
must be an integer, which is argc
of the command.i
in argc
, Buf[0]
must be '$'
; Buf[1]
must be a number(could be long), which is the size of argv[i]
. Read Buf[1]
length of data from Buf and save it into argv[i]
argv[0]
is the command name. Search it in CommandTable via lookupCommand(argv[0]->ptr)
.cmd->proc(fakeClient)
rdbLoad() in rdb.c
rio
streamREDIS
, following 4 is the RDB_VERSION
. If version is too old, RDB recovery can't be used.OP_CODE
. See below for OP_CODE
details.OP_CODE = RDB_OPCODE_SELECTDB
, store current db number based on the value after.OP_CODE = RDB_OPCODE_RESIZEDB
. expand the db size based on the value after.OP_CODE
in RDB_OPCODE_EXPIRETIME | RDB_OPCODE_EXPIRETIME_MS
, store key expiration info based on the value after.OP_CODE
in RDB_OPCODE_FREQ | RDB_OPCODE_IDLE
, store key eviction score based on the value after.OP_CODE = RDB_OPCODE_EOF
, jump out of the loop.OP_CODE
in RDB_TYPE_*
family, read the next string as the key of a key-value pair and the following chunk of data as the value. Chunk's size and format depend on which RDB_TYPE
it is.RDB_VERSION > 5
and CRC checksum is enabled on RDB, read the last part of the stream after RDB_OPCODE_EOF
. Abort if mismatch.RDB = |REDIS|RDB_VERSION|DB_SECTION|...|DB_SECTION|EOF|CRC_CHECKSUM|
DB_SECTION = |RDB_OPCODE_SELECTDB|DB_NUM|RDB_OPCODE_RESIZEDB|DB_SIZE|KEY_VALUE|...|KEY_VALUE|
KEY_VALUE = |OPTIONAL_KEY_EXPIRE_INFO|OPTIONAL_KEY_LRU_LFU_INFO|RDB_TYPE|KEY|VALUE|
OPTIONAL_KEY_EXPIRE_INFO = |RDB_OPCODE_EXPIRETIME|EXPIRE_IN_SEC| or |RDB_OPCODE_EXPIRETIME_MS|EXPIRE_IN_MS|
OPTIONAL_KEY_LRU_LFU_INFO = |RDB_OPCODE_FREQ|LFU_SCORE| or |RDB_OPCODE_IDLE|LRU_SCORE|
RDB_TYPE = |RDB_TYPE_STRING|RDB_TYPE_LIST|RDB_TYPE_SET|RDB_TYPE_ZSET|RDB_TYPE_HASH|RDB_TYPE_HASH|RDB_TYPE_ZSET_2|
複製代碼
int64
is a db number. Read the value and store it such that Redis will write to the correct DB later on.int64
is a db size. Read the value and expand the corresponding DB's db->dict
and db->expire
to avoid unnecessary rehash during key injection.int32
is an expiration time of a key in second. Read the value and store it such that Redis will set
the key with correct expiration time.int64
is an expiration time of a key in millisecond. Read the value and store it such that Redis will set
the key with correct expiration time.byte
is an LFU score of a key in sacle of 0-255. Read the value and store it such that Redis could handle the key correctly during eviction if server.maxmemory_policy & MAXMEMORY_FLAG_LFU
.int64
is an LRU score of a key. Read the value and store it such that Redis could handle the key correctly during eviction if server.maxmemory_policy & MAXMEMORY_FLAG_LRU
.!eventLoop->stop
is false.aeApiPoll(eventLoop, tvp)
. API being used is platform dependent.fe->mask & AE_BARRIER
. If AE_BARRIER is set, process write event first. Else, read event first.processTimeEvents(eventLoop)
.