redis 5.0 命令处理流程
初始化事件驱动数据结构:
initServer 中调用 aeCreateEventLoop 方法初始化 server.el 属性,然后调用 listenToPort 方法设置 listen 的 fd,并为这些 fd 绑定读事件 anetTcpHandler。
anetTcpHandler 循环 1000 次 accept,然后对于连接调用 acceptCommonHandler 方法。
acceptCommandHandler方法:
根据客户端fd创建client结构。
- 分配内存给client。
- 设置fd的非阻塞、不延迟、和tcpkeepalive、并为客户端fd绑定读事件readQueryFromClient。
- 默认为客户端绑定db 0,设置
c->db = &server.db[0]
。 - 自增server.next_client_id。
- 把client添加server.clients链表,并设置
c->client_list_node = listLast(server.clients)
保证能快速找到客户端在server中的所处的位置。 - 把客户端根据其id插入
server.client_index
的基数数。
如果当前客户端数量大于最大客户端数量就返回-ERR max number of clients reached
,并释放客户端。
如果开启了保护模式,则对非本地请求都直接返回并释放客户端。
readQueryFromClient方法:
如果不是master模式,则调用processInputBuffer方法进行处理。
processInputBuffer
- 设置当前客户端:
server.current_client = c
- 根据第一个字节是否为
*
确定是否为multibulk模式,是则设置为PROTO_REQ_MULTIBULK
,否则设置为PROTO_REQ_INLINE
。 - 解析参数
- 如果为
PROTO_REQ_INLINE
模式,则调用processInlineBuffer方法。 - 如果为
PROTO_REQ_MULTIBULK
模式,则调用processMultibulkBuffer
方法。
- 如果为
- 如果第一个参数等于quit,则回复+OK\r\n,添加标志CLIENT_CLOSE_AFTER_REPLY。
- 查询并调用命令:processCommand
- 查询命令:lookupCommand,从
server.commands
字典中查询。 - 查询成功则调用call方法来调用命令,调用
c->cmd->proc
函数指针来调用命令。
- 查询命令:lookupCommand,从
server.commands命令表初始化
initServerConfig方法中,创建2个字典,分别是server.command、server.orig_command,然后调用populateCommandTable方法把redisCommandTable数组中的命令都加到server.command和server.orig_command中。然后再单独设置以下命令:
server.delCommand = lookupCommandByCString("del");
server.multiCommand = lookupCommandByCString("multi");
server.lpushCommand = lookupCommandByCString("lpush");
server.lpopCommand = lookupCommandByCString("lpop");
server.rpopCommand = lookupCommandByCString("rpop");
server.zpopminCommand = lookupCommandByCString("zpopmin");
server.zpopmaxCommand = lookupCommandByCString("zpopmax");
server.sremCommand = lookupCommandByCString("srem");
server.execCommand = lookupCommandByCString("exec");
server.expireCommand = lookupCommandByCString("expire");
server.pexpireCommand = lookupCommandByCString("pexpire");
server.xclaimCommand = lookupCommandByCString("xclaim");
server.xgroupCommand = lookupCommandByCString("xgroup");
标签:5.0,调用,流程,redis,server,命令,client,lookupCommandByCString,客户端
From: https://www.cnblogs.com/Lht1/p/18107431