【Redis源码】Redis命令执行过程
2023-06-13 09:11:31 时间
简介
需要了解Redis命令执行过程,请先了解Redis启动过程和Redis事件监听。
在Redis事件监听中我们了解到在创建文件监听事件的时候 acceptTcpHandler
就是的执行函数。具体实现如下:
for (j = 0; j < server.ipfd_count; j++) {
if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL) == AE_ERR){
erverPanic("Unrecoverable error creating server.ipfd file event.");
}
}
总体处理流程
创建连接
当有命令执行的时候,acceptTcpHandler函数中会调用acceptCommonHandler函数。acceptCommonHandler函数会判断已经连接的客户端时候已经超过10000(maxclients配置的值,默认为10000)。
创建Redis连接。代码如下:
if ((c = createClient(conn)) == NULL) {
char conninfo[100];
serverLog(LL_WARNING,
"Error registering fd event for the new client: %s (conn: %s)",
connGetLastError(conn),
connGetInfo(conn, conninfo, sizeof(conninfo)));
connClose(conn); /* May be already closed, just ignore errors */
return;
}
接受命令
函数readQueryFromClient用于接受已经创建好的连接的命令。最后处理命令的函数为processCommand,执行命令:
int processCommand(client *c) {
moduleCallCommandFilters(c);
/* 优先处理退出命令 */
if (!strcasecmp(c->argv[0]->ptr,"quit")) {
addReply(c,shared.ok);
c->flags |= CLIENT_CLOSE_AFTER_REPLY;
return C_ERR;
}
/* 在命令表里面查找命令*/
c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr);
if (!c->cmd) {
// 找不到命令
return C_OK;
} else if ((c->cmd->arity > 0 && c->cmd->arity != c->argc) ||
(c->argc < -c->cmd->arity)) {
// 命令参数不对
return C_OK;
}
/* 是否已经认证 */
int auth_required = (!(DefaultUser->flags & USER_FLAG_NOPASS) ||
(DefaultUser->flags & USER_FLAG_DISABLED)) &&
!c->authenticated;
if (auth_required) {
/* 没有认证返回*/
if (!(c->cmd->flags & CMD_NO_AUTH)) {
flagTransaction(c);
addReply(c,shared.noautherr);
return C_OK;
}
}
/* 检查是否已经超过最大内存*/
if (server.maxmemory && !server.lua_timedout) {
// return 错误;
}
// 进行其他检查项
/* 执行命令 */
if (c->flags & CLIENT_MULTI &&
c->cmd->proc != execCommand && c->cmd->proc != discardCommand &&
c->cmd->proc != multiCommand && c->cmd->proc != watchCommand)
{
queueMultiCommand(c);
addReply(c,shared.queued);
} else {
// 调用命令表里面吗对应命令的实现函数。
call(c,CMD_CALL_FULL);
c->woff = server.master_repl_offset;
if (listLength(server.ready_keys))
handleClientsBlockedOnKeys();
}
return C_OK;
}
命令表详见:《Redis 启动过程分析》中,初始化命令表部分。
至此,命令处理的整个过程完成。
相关文章
- springboot 之集成Redis
- 源码安装Linux系统下Redis源码安装指南(linux下redis)
- Redis缓存:了解生命周期的关键(redis缓存生命周期)
- Redis执行失败深思熟虑后的惨烈失败(执行redis失败)
- 自学研究Redis手写Redis源码的过程(手写redis源码)
- 解析Redis源码,学习存储引擎之美(怎样研究redis源码)
- 腾讯云 Redis云中数据存储专家(腾讯云redis介绍)
- 极速安装:手把手教你源码安装Redis(源码安装redis)
- 抢到手软秒杀PHP使用Redis进行流量管理(秒杀php用redis)
- 学会看懂Redis源码 尽享学习好收获(看懂redis源码好处)
- 掌握Redis集群登录命令实战(登录redis集群命令)
- 本地连接服务器Redis建立稳固的数据链接(本地连服务器redis)
- 开源让Redis实现最大效能(源码连接redis)
- 深入研究Redis源码分析(源码分析redis)
- 分析SSM搭配Redis深度源码分析(ssm整合redis源码)
- 深度学习SSM整合Redis的实战经验(ssm嵌入redis)
- 从源码解读 SSH 与 Redis 的安全性(ssh redis源码)
- 删除Redis回收内存的秘诀(删除redis的缓存文件)
- 让Redis存储哪些数据(哪些数据存入redis)
- 快速简便命令行快速执行Redis操作(命令行直接执行redis)
- 学习Redis源码在研究分布式原理中获取灵感(如何阅读redis源码)
- 安全基于Redis集群的数据安全保障策略(redis集群保证数据)
- Redis集群实现散列值分片存储(redis集群hash值)
- Redis键位设置踩点把握性能(redis键位设置)
- Redis如何设置最大值递增(redis 递增 最大值)
- 库远程利用Redis访问数据库(redis远程访问数据)
- 解析Redis 跳跃表深入解读源码(redis 跳跃表源码)
- Redis集群单数台部署实战篇(redis集群单数台)
- 使用Redis连接池提高效率与性能(redis连接池怎么使用)
- 基于Redis的数据运维框架(redis 运维框架)
- 跳出传统Redis的模糊Like查询(redis模糊like)