Valkey源码剖析(20):客户端表示¶
Valkey使用server.h/client结构表示与服务器连接的每个客户端,该结构包含了客户端的ID、网络连接信息、客户端正在执行的命令及其参数、参数个数等多项信息:
typedef struct client {
/* Basic client information and connection. */
// 自动递增的客户端唯一ID
uint64_t id; /* Client incremental unique ID. */
// 网络连接
connection *conn;
/* Input buffer and command parsing fields */
// 查询缓冲区
sds querybuf; /* Buffer we use to accumulate client queries. */
// 已读取查询缓冲区的偏移量
size_t qb_pos; /* The position we have read in querybuf. */
// 命令参数
robj **argv; /* Arguments of current command. */
// 命令参数数量
int argc; /* Num of arguments of current command. */
// ...
} client;
当Valkey服务器接收到客户端的网络连接请求时,networking.c/acceptCommonHandler()函数就会被调用,并继而调用networking.c/createClient()函数,从而为客户端创建出相应的client结构:
void acceptCommonHandler(connection *conn, struct ClientFlags flags, char *ip) {
client *c;
// ...
// 为连接创建客户端
if ((c = createClient(conn)) == NULL) {
serverLog(LL_WARNING, "Error registering fd event for the new client connection: %s (addr=%s laddr=%s)",
connGetLastError(conn), addr, laddr);
connClose(conn); /* May be already closed, just ignore errors */
return;
}
// ...
}
// 创建并初始化一个空白的客户端
client *createClient(connection *conn) {
client *c = zmalloc(sizeof(client));
// 连接可以为NULL,用于在Lua脚本等环境中执行命令(因为Redis执行命令必须在客户端上下文中)
if (conn) {
// 绑定查询读取处理器
connSetReadHandler(conn, readQueryFromClient);
// 设置私有数据
connSetPrivateData(conn, c);
// 设置状态
conn->flags |= CONN_FLAG_ALLOW_ACCEPT_OFFLOAD;
}
// 分配输出缓冲区空间
c->buf = zmalloc_usable(PROTO_REPLY_CHUNK_BYTES, &c->buf_usable_size);
// 选择数据库
selectDb(c, 0);
// 分配客户端ID
uint64_t client_id = atomic_fetch_add_explicit(&server.next_client_id, 1, memory_order_relaxed);
// 设置客户端ID
c->id = client_id;
// 设置使用的RESP版本
#ifdef LOG_REQ_RES
reqresReset(c, 0);
c->resp = server.client_default_resp;
#else
c->resp = 2;
#endif
// 绑定连接
c->conn = conn;
// 初始化其他属性……
c->name = NULL;
c->lib_name = NULL;
c->lib_ver = NULL;
c->bufpos = 0;
// ...
// 将当前客户端添加到服务器全局客户端链表中
if (conn) linkClient(c);
// ...
return c;
}
在为客户端创建对应的client结构之后,服务器就可以使用这个结构来存储客户端执行命令时的上下文,比如命令请求、命令回复和当前正在执行的命令等等,具体的内容将在接下来的文章中进行介绍。
黄健宏
2026.1.26