Previous tutorials have started with the basic Redis data structures, but until those data structures are implemented, how the Redis server handles the flow of client commands and how the request events are handled:
- The server starts listening
- Accept commands and parse them
- Execute the command
- Returns command request data
Redis server is a typical event driver, so the above event handling is particularly important. Redis divides events into two broad categories: file events and time times. File events are socket read and write events. Time events are used to process scheduled services that are executed periodically.
To better understand the server-side and client-side interaction, take a look at the redis data organization structure.
robj
Redis is a KV database, key can only be string, value is represented by the structure robj, it can be a string, list, collection, etc., this depends on robj’s type field.
typedef struct redisObject {
unsigned type:4; // Type (4 bits) -> 5 types defined in
unsigned encoding:4; // Code -> 11 types
unsigned lru:REDIS_LRU_BITS; // The last time the object was accessed
int refcount; // Reference count
void *ptr; // A pointer to the actual value
} robj;
Copy the code
ptr
: is a pointer to a data structure actually storedrefcount
: Indicates the number of times an object is referenced to achieve object sharinglru
: used to implement cache elimination policy, can be inmaxmemory_policy
Configure a cache elimination policy for maximum memory limitsLFU
Go:updateLFU(val)
.LRU
Go:LRU_CLOCK()
, gets the current time and updates. The store isLast visit time 和 visits
Redis may store different data structures for different types of objects, depending on encoding, and encoding is not immutable throughout the object’s life cycle.
redisDb
Robj encapsulates the basic data structure. In addition, a structure is needed to encapsulate the database, which is used to manage the related data and related operations of the database. This is redisDb.
typedef struct redisDb {
dict *dict; // Database key space, which holds all the key pairs in the database
dict *expires; // The expiration time of the key, the key of the dictionary is the key, the value of the dictionary is the expiration event UNIX timestamp
dict *blocking_keys; // The key that is blocking
dict *ready_keys; // Unblocking key
dict *watched_keys; // The key being monitored by the WATCH command
int id; // Database number
long long avg_ttl; // Average TTL of database keys, statistics
list *defrag_later; // Try to defragment the list of keys one by one
} redisDb;
Copy the code
Two important attributes: dict and Expires
- like
scan, move, sort
Such is thedict
Key space operations; expire, persist
Such is theexpires
The operation of an expired hash table
redisServer
struct redisServer {. redisDb *db;// Redis database
int dbnum; // Db number, 0-16
dict *commands // All commands are stored in this dictionary. aeEventLoop *el;// Event loop
list *clients; // All clients currently connected to the server. }Copy the code
There are too many fields in redisServer.
RedisServer, redisDb, dict