structredisCommand { // 声明类数据 constchar *declared_name; // 标识命令名,之所以定义为指针是为了兼容原生命令和sds命令 constchar *summary; // 命令概要,可选 constchar *complexity; // 复杂度描述, 可选 constchar *since; // 命令的首次发布版本,可选 int doc_flags; /* Flags for documentation (see CMD_DOC_*). */ constchar *replaced_by; // 如果命令被废弃,则填写其继任者 constchar *deprecated_since; // 命令何时被废弃 redisCommandGroup group; // 命令组 commandHistory *history; // 命令历史 int num_history; constchar **tips; /* An array of strings that are meant to be tips for clients/proxies regarding this command */ int num_tips; redisCommandProc *proc; // 命令实现 int arity; // 参数个数 uint64_t flags; /* Command flags, see CMD_*. */ uint64_t acl_categories; // ACL分类 keySpec *key_specs; int key_specs_num; /* Use a function to determine keys arguments in a command line. * Used for Redis Cluster redirect (may be NULL) */ redisGetKeysProc *getkeys_proc; // 使用函数确定命令行中的键参数 int num_args; // 命令参数数组长度 structredisCommand *subcommands;// 子命令数组 structredisCommandArg *args;// 命令参数数组 #ifdef LOG_REQ_RES /* Reply schema */ structjsonObject *reply_schema; #endif
// 运行时填充的数据 longlong microseconds, calls, rejected_calls, failed_calls; int id; // 命令id,从0开始,在运行时分配,用于acl检查;如果当前连接的用户具有此命令位,则此连接能执行给定的命令。[位图] sds fullname; // sds描述的命令全名 structhdr_histogram* latency_histogram;/*points to the command latency command histogram (unit of time nanosecond) */ keySpec legacy_range_key_spec; /* The legacy (first,last,step) key spec is * still maintained (if applicable) so that * we can still support the reply format of * COMMAND INFO and COMMAND GETKEYS */ dict *subcommands_dict; // 保留子命令的字典,键是子命令的sds名称(非全名),值为redisCommand的指针。 structredisCommand *parent; structRedisModuleCommand *module_cmd;/* A pointer to the module command data (NULL if native command) */ };
typedefstructclient { uint64_t id; /* Client incremental unique ID. */ uint64_t flags; /* Client flags: CLIENT_* macros. */ connection *conn; int resp; /* RESP protocol version. Can be 2 or 3. */ redisDb *db; /* Pointer to currently SELECTed DB. */ robj *name; /* As set by CLIENT SETNAME. */ robj *lib_name; /* The client library name as set by CLIENT SETINFO. */ robj *lib_ver; /* The client library version as set by CLIENT SETINFO. */ sds querybuf; /* Buffer we use to accumulate client queries. */ size_t qb_pos; /* The position we have read in querybuf. */ size_t querybuf_peak; /* Recent (100ms or more) peak of querybuf size. */ int argc; /* Num of arguments of current command. */ robj **argv; /* Arguments of current command. */ int argv_len; /* Size of argv array (may be more than argc) */ int original_argc; /* Num of arguments of original command if arguments were rewritten. */ robj **original_argv; /* Arguments of original command if arguments were rewritten. */ size_t argv_len_sum; /* Sum of lengths of objects in argv list. */ structredisCommand *cmd, *lastcmd;/* Last command executed. */ structredisCommand *realcmd;/* The original command that was executed by the client, Used to update error stats in case the c->cmd was modified during the command invocation (like on GEOADD for example). */ user *user; /* User associated with this connection. If the user is set to NULL the connection can do anything (admin). */ int reqtype; /* Request protocol type: PROTO_REQ_* */ int multibulklen; /* Number of multi bulk arguments left to read. */ long bulklen; /* Length of bulk argument in multi bulk request. */ list *reply; /* List of reply objects to send to the client. */ unsignedlonglong reply_bytes; /* Tot bytes of objects in reply list. */ list *deferred_reply_errors; /* Used for module thread safe contexts. */ size_t sentlen; /* Amount of bytes already sent in the current buffer or object being sent. */ time_t ctime; /* Client creation time. */ long duration; /* Current command duration. Used for measuring latency of blocking/non-blocking cmds */ int slot; /* The slot the client is executing against. Set to -1 if no slot is being used */ dictEntry *cur_script; /* Cached pointer to the dictEntry of the script being executed. */ time_t lastinteraction; /* Time of the last interaction, used for timeout */ time_t obuf_soft_limit_reached_time; int authenticated; /* Needed when the default user requires auth. */ int replstate; /* Replication state if this is a slave. */ int repl_start_cmd_stream_on_ack; /* Install slave write handler on first ACK. */ int repldbfd; /* Replication DB file descriptor. */ off_t repldboff; /* Replication DB file offset. */ off_t repldbsize; /* Replication DB file size. */ sds replpreamble; /* Replication DB preamble. */ longlong read_reploff; /* Read replication offset if this is a master. */ longlong reploff; /* Applied replication offset if this is a master. */ longlong repl_applied; /* Applied replication data count in querybuf, if this is a replica. */ longlong repl_ack_off; /* Replication ack offset, if this is a slave. */ longlong repl_aof_off; /* Replication AOF fsync ack offset, if this is a slave. */ longlong repl_ack_time;/* Replication ack time, if this is a slave. */ longlong repl_last_partial_write; /* The last time the server did a partial write from the RDB child pipe to this replica */ longlong psync_initial_offset; /* FULLRESYNC reply offset other slaves copying this slave output buffer should use. */ char replid[CONFIG_RUN_ID_SIZE+1]; /* Master replication ID (if master). */ int slave_listening_port; /* As configured with: REPLCONF listening-port */ char *slave_addr; /* Optionally given by REPLCONF ip-address */ int slave_capa; /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */ int slave_req; /* Slave requirements: SLAVE_REQ_* */ multiState mstate; /* MULTI/EXEC state */ blockingState bstate; /* blocking state */ longlong woff; /* Last write global replication offset. */ list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */ dict *pubsub_channels; /* channels a client is interested in (SUBSCRIBE) */ dict *pubsub_patterns; /* patterns a client is interested in (PSUBSCRIBE) */ dict *pubsubshard_channels; /* shard level channels a client is interested in (SSUBSCRIBE) */ sds peerid; /* Cached peer ID. */ sds sockname; /* Cached connection target address. */ listNode *client_list_node; /* list node in client list */ listNode *postponed_list_node; /* list node within the postponed list */ listNode *pending_read_list_node; /* list node in clients pending read list */ void *module_blocked_client; /* Pointer to the RedisModuleBlockedClient associated with this * client. This is set in case of module authentication before the * unblocked client is reprocessed to handle reply callbacks. */ void *module_auth_ctx; /* Ongoing / attempted module based auth callback's ctx. * This is only tracked within the context of the command attempting * authentication. If not NULL, it means module auth is in progress. */ RedisModuleUserChangedFunc auth_callback; /* Module callback to execute * when the authenticated user * changes. */ void *auth_callback_privdata; /* Private data that is passed when the auth * changed callback is executed. Opaque for * Redis Core. */ void *auth_module; /* The module that owns the callback, which is used * to disconnect the client if the module is * unloaded for cleanup. Opaque for Redis Core.*/
/* If this client is in tracking mode and this field is non zero, * invalidation messages for keys fetched by this client will be sent to * the specified client ID. */ uint64_t client_tracking_redirection; rax *client_tracking_prefixes; /* A dictionary of prefixes we are already subscribed to in BCAST mode, in the context of client side caching. */ /* In updateClientMemoryUsage() we track the memory usage of * each client and add it to the sum of all the clients of a given type, * however we need to remember what was the old contribution of each * client, and in which category the client was, in order to remove it * before adding it the new value. */ size_t last_memory_usage; int last_memory_type;
listNode *ref_repl_buf_node; /* Referenced node of replication buffer blocks, * see the definition of replBufBlock. */ size_t ref_block_pos; /* Access position of referenced buffer block, * i.e. the next offset to send. */
/* list node in clients_pending_write list */ listNode clients_pending_write_node; /* Response buffer */ size_t buf_peak; /* Peak used size of buffer in last 5 sec interval. */ mstime_t buf_peak_last_reset_time; /* keeps the last time the buffer peak value was reset */ int bufpos; size_t buf_usable_size; /* Usable size of buffer. */ char *buf; #ifdef LOG_REQ_RES clientReqResInfo reqres; #endif } client;