在redis.c的initServerConfig()方法中,通过调用dictCreate方法初始化server端的命令表。这个命令表是一个hashtable,可以通过key找到相关的命令:

/* Command table -- we initiialize it here as it is part of the
* initial configuration, since command names may be changed via
* redis.conf using the rename-command directive. */
server.commands = dictCreate(&commandTableDictType, NULL);
server.orig_commands = dictCreate(&commandTableDictType, NULL);
populateCommandTable();
server.delCommand = lookupCommandByCString("del");
server.multiCommand = lookupCommandByCString("multi");
server.lpushCommand = lookupCommandByCString("lpush");
server.lpopCommand = lookupCommandByCString("lpop");
server.rpopCommand = lookupCommandByCString("rpop");

initServer()函数在初始化服务端的基本配置时,已经提前创建了客户端的回调函数。具体的调用为:
1.创建客户端的文件读事件的回调:acceptTcpHandler/acceptUnixHandler
2.一旦接收到客户端连接请求后,调用acceptCommonHandler()方法。在接收到客户端请求后,可以得到客户端的fd(file description),这个fd在调用acceptCommonHandler时会传入。
3.acceptCommonHandler内部根据fd调用createClient创建redis客户端的上下文信息。
4.createClient内部又创建了一个事件回调函数readQueryFromClient,用于读取客户端的传入的信息。
5.readQueryFromClient从客户端读取实际的请求内容,然后会做一个初步判断客户端的请求内容是否合理。不合理的请求在这里直接被拦截处理了。这里判断请求是否合理主要是判断网络层面的内容是否合理。如果网络层相关的请求合理的话,调用processInputBuffer方法解析客户端的请求类型。
6.processInputBuffer会解析客户端的reqtype是inline还是multibulk的。如果是inline的,调用processInlineBuffer函数类解析出argv/argc;否则调用processMultibulkBuffer。如果argc没有,直接重置客户端;否则调用processCommand方法处理客户端的命令。
7.processCommand首先根据argv的内容,然后调用lookupCommand()方法从server.commands中找到需要执行的命令,然后将找到的命令赋值到client的cmd和lastcmd字段上。
c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr);
8.找到相关的命令后,调用call方法,执行客户端的命令。执行命令很简单,因为上一步中已经找到了客户端的cmd了。每个命令都有一个proc方法,方法接受一个redisclient的参数。这里只需要调用c->cmd->proc(),然后将c传入即可。
9.至此,redis执行客户端命令的过程就算结束了。

Redis中的执行命令的过程的更多相关文章

  1. Redis中的Scan命令踩坑记

    1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这 ...

  2. 如何在sublime编辑器中,执行命令行脚本

    我有个愿意,在执行命令行时,不打开那个黑乎乎命令行窗口,如果编辑器内置支持就好了. 打开vs code 和 sublime,分别按快捷键 Ctrl + ·(tab键上面那个键),vs code可以提供 ...

  3. php中代码执行&&命令执行函数

    转自i春秋 1.eval()函数 #传入的参数必须为PHP代码,既需要以分号结尾. #命令執行:cmd=system(whoami); #菜刀连接密码:cmd <?php @eval($_POS ...

  4. Redis中的Scan命令的使用

    Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行 ...

  5. Redis中info all命令解析

    127.0.0.1:8376> info all# Server    --- 服务器信息redis_version:2.8.20 -- redis服务器版本redis_git_sha1:000 ...

  6. shell 脚本中后台执行命令 &

    最近遇到一个问题, 执行脚本,脚本调用 一个命令,命令(deamon)是一个守护进程,为了调试,取消了守护进程模式.导致命令后边的其他命令(echo "456")都无法执行. de ...

  7. redis中setbit bitcount命令详解

    bitmap,位图,即是使用bit. redis字符串是一个字节序列. 1 Byte = 8 bit SETBIT key offset value 设置或者清空key的value(字符串)在offs ...

  8. cmd到指定目录并执行命令 mysql到bin目录并执行命令 cmd bat进入指定文件夹中并执行命令

    其实就一条命令:(保存为bat格式,注意:有两个and希腊字母 && )cmd /k "cd /d Your ProjectPath&&Your CMD co ...

  9. Redis中的常用命令哪些?

    a.hset 存储一个哈希键值对的集合 b.hget获取一个哈希键的值c.hdel 删除一个或多个字段 d.hgetall 获取一个哈希是键值对的集合 e.lpush key value向链表左侧添加 ...

随机推荐

  1. Debian 8下手工安装 Eclipse CDT neon.2

    从 http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neon2 下载 eclipse-cpp-neon-2-li ...

  2. 一窍懂PID

    这是学习PID时的理解,做个笔记! 一:首选,说一下一些基本概念,为了更好理解. PID:就是对输入偏差进行比例积分微分运算,运算的叠加结果去控制执行机构. P(proportion):比例,就是对输 ...

  3. Collection类,泛型

    Collection(接口) 所有超级接口: Iterable<E> 一.集合 1.集合的介绍&集合和数组的区别 什么是集合:java中的一种容器 什么是数组:java中的一种容器 ...

  4. #221 Iterate Through an Array with a For Loop

    迭代输出一个数组的每个元素是 JavaScript 中的常见需求, for 循环可以做到这一点. 下面的代码将输出数组 arr 的每个元素到控制台: var arr = [10,9,8,7,6];fo ...

  5. 使用MvvmCross框架实现Xamarin.Forms的汉堡菜单布局

    注:本文是英文写的,偷懒自动翻译过来了,原文地址:Implementing MasterDetail layout in Xamarin.Forms by MvvmCross 欢迎大家关注我的公众号: ...

  6. Python自动化编程-树莓派的介绍与使用(一)

    Raspberry Pi(中文名为“树莓派”,简写为RPi,(或者RasPi / RPI) [1]  是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于Linux.  随着Windo ...

  7. Spring5中的DispatcherServlet初始化

    Spring MVC像许多其它Web框架,被设计围绕前端控制器(DispatcherServlet)实际的工作是由可配置的,委托组件执行提供了一种用于请求处理的共享算法.这个模型是灵活的,支持不同的工 ...

  8. ubuntu18.04LTS设置静态IP

    ubuntu18.04LTS设置静态IP 因为Ubuntu18.04采用的是netplan来管理network.所以在/etc/netplan/目录下有一个以yaml结尾的文件.比如01-networ ...

  9. Git使用详细教程(7):.gitignore使用详解

    Git提供了一个.gitignore文件,帮助我们忽略掉一些不想或者不能提交到版本控制器中的文件.这个文件的使用时必须要掌握的. *.a # 忽略所有目录下的.a结尾的文件 !lib.a # 但lib ...

  10. redis订阅关闭异常解决

    redis订阅关闭异常解决 应用程序模块订阅redis运行一段时间出现一直重连Redis服务,日志如下: 2019-04-28 10:06:17,551 ERROR org.springframewo ...