Redis服务端执行命令基本流程

原创 2016年05月31日 22:41:06

服务端执行命令基本流程:

如 set  a  "100" 这样的命令,在客户端被转换成redis协议格式发送至服务端,服务端收到后,解析字符串,得到三个RedisObject,object内部内容分别为set ,a ,100
  • 对于100这样的数字,redis初始时会建立redis.h/REDIS_SHARED_INTEGERS个常量对象,默认0-10000,如100这样的直接在原本建立好的redisobject的引用上+1,这样子引用计数+对象共享,避免了反复分配内存的消耗。
  • 对于其他字符串,和其他类型,如果每个object都进行引用计数和对象共享,则会消耗大量CPU时间,所以Redis只对整数值的字符串对象进行初始化和引用计数
struct sharedObjectsStruct {
    robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *cnegone, *pong, *space,
    *colon, *nullbulk, *nullmultibulk, *queued,
    *emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
    *outofrangeerr, *noscripterr, *loadingerr, *slowscripterr, *bgsaveerr,
    *masterdownerr, *roslaveerr, *execaborterr, *noautherr, *noreplicaserr,
    *busykeyerr, *oomerr, *plus, *messagebulk, *pmessagebulk, *subscribebulk,
    *unsubscribebulk, *psubscribebulk, *punsubscribebulk, *del, *rpop, *lpop,
    *lpush, *emptyscan, *minstring, *maxstring,
    *select[REDIS_SHARED_SELECT_CMDS],
    *integers[REDIS_SHARED_INTEGERS],//here<-------------------
    *mbulkhdr[REDIS_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
    *bulkhdr[REDIS_SHARED_BULKHDR_LEN];  /* "$<value>\r\n" */
};

且服务端会为每个redis连接维护一个redisClient对象,


/* redis.h
     With multiplexing we need to take per-client state.
 * Clients are taken in a liked list.
 *
 * 因为 I/O 复用的缘故,需要为每个客户端维持一个状态。
 *
 * 多个客户端状态被服务器用链表连接起来。
 */
typedef struct redisClient {

    // 套接字描述符
    int fd;

    // 当前正在使用的数据库
    redisDb *db;

    // 当前正在使用的数据库的 id (号码)
    int dictid;

    // 客户端的名字
    robj *name;             /* As set by CLIENT SETNAME */

    // 查询缓冲区
    sds querybuf;

    // 查询缓冲区长度峰值
    size_t querybuf_peak;   /* Recent (100ms or more) peak of querybuf size */

    // 参数数量
    int argc;

    // 参数对象数组
    robj **argv;

    // 记录被客户端执行的命令
    struct redisCommand *cmd, *lastcmd;

    // 请求的类型:内联命令还是多条命令
    int reqtype;

    // 剩余未读取的命令内容数量
    int multibulklen;       /* number of multi bulk arguments left to read */

    // 命令内容的长度
    long bulklen;           /* length of bulk argument in multi bulk request */

    // 回复链表
    list *reply;

    // 回复链表中对象的总大小
    unsigned long reply_bytes; /* Tot bytes of objects in reply list */

    // 已发送字节,处理 short write 用
    int sentlen;            /* Amount of bytes already sent in the current
                               buffer or object being sent. */

    // 创建客户端的时间
    time_t ctime;           /* Client creation time */

    // 客户端最后一次和服务器互动的时间
    time_t lastinteraction; /* time of the last interaction, used for timeout */

    // 客户端的输出缓冲区超过软性限制的时间
    time_t obuf_soft_limit_reached_time;

    // 客户端状态标志
    int flags;              /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
..............
...............
    /* Response buffer */
    // 回复偏移量
    int bufpos;
    // 回复缓冲区
    char buf[REDIS_REPLY_CHUNK_BYTES];

} redisClient;

根据字符串set查找命令表

//redis.h
struct redisCommand redisCommandTable[] = {
    {"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
    {"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0},
    {"setnx",setnxCommand,3,"wm",0,NULL,1,1,1,0,0},
    {"setex",setexCommand,4,"wm",0,NULL,1,1,1,0,0},
    {"psetex",psetexCommand,4,"wm",0,NULL,1,1,1,0,0},
    {"append",appendCommand,3,"wm",0,NULL,1,1,1,0,0},
    {"strlen",strlenCommand,2,"r",0,NULL,1,1,1,0,0},
    {"del",delCommand,-2,"w",0,NULL,1,-1,1,0,0},
    {"exists",existsCommand,2,"r",0,NULL,1,1,1,0,0},
    {"setbit",setbitCommand,4,"wm",0,NULL,1,1,1,0,0},
    {"getbit",getbitCommand,3,"r",0,NULL,1,1,1,0,0},
    ....
};
//redis.h
struct redisCommand {
    // 命令名字
    char *name;
    // 实现函数
    redisCommandProc *proc;
    // 参数个数
    int arity;
    // 字符串表示的 FLAG
    char *sflags; /* Flags as string representation, one char per flag. */
    // 实际 FLAG
    int flags;    /* The actual flags, obtained from the 'sflags' field. */
    /* Use a function to determine keys arguments in a command line.
     * Used for Redis Cluster redirect. */
    // 从命令中判断命令的键参数。在 Redis 集群转向时使用。
    redisGetKeysProc *getkeys_proc;
    /* What keys should be loaded in background when calling this command? */
    // 指定哪些参数是 key
    int firstkey; /* The first argument that's a key (0 = no keys) */
    int lastkey;  /* The last argument that's a key */
    int keystep;  /* The step between first and last key */
    // 统计信息
    // microseconds 记录了命令执行耗费的总毫微秒数
    // calls 是命令被执行的总次数
    long long microseconds, calls;
};

查表得到setCommand,令redisClient中的cm指向它,client->cmd->proc(client)执行命令,调用setCommand,处理redisCommadn中其他选项参数,最后调用setGenericCommand处理set key value的指令

redis命令执行流程分析

Redis中各种操作都可以通过命令来完成,因此理解redis对命令的处理流程会有助于理解redis的整个流程。本文主要对redis的命令处理流程进行详细分析。 Redis将所有它能支持的命令以及对应...
  • hjx_1000
  • hjx_1000
  • 2014年05月27日 11:26
  • 2535

Redis从文件中批量执行命令

在redis中,如果要批量执行某些命令,在redis的redis-cli下,只能一条条的执行指令,实在太麻烦了!  如果把要执行的命令一行行存储到文件中,然后一次性执行完成。 1、创建文件 ...
  • u012689336
  • u012689336
  • 2016年11月25日 15:20
  • 3121

redis系列(六)客户端和服务器

这篇博客比较简单,主要是刚开始的时候不必对 redis 内部的一些有太清楚的了解。待基本上对 redis 有一个初步的了解之后,在对 redis 内部的一些原理,函数以及源码进行研究,这个我会在后续的...
  • zhihui0317
  • zhihui0317
  • 2017年03月21日 15:22
  • 413

redis服务端基本命令

参考文章:http://www.cnblogs.com/daijinjiang/archive/2013/01/09/2852654.html redis服务端基本命令 ...
  • feifuzeng
  • feifuzeng
  • 2017年06月27日 15:44
  • 127

windows下如何打开cmd窗口就能执行redis的相关命令

自从安装了redis,每次要执行redis的相关命令,都需要打开cmd窗口,然后输入cd,改变当前路径到安装redis的路径下,感觉很不方便。因为知道可以设置windows的环境变量,增加redis安...
  • sxf359
  • sxf359
  • 2017年06月08日 16:25
  • 1516

Redis使用管道一次I\O执行多条命令(转)

转自:http://www.yiibai.com/redis/redis_pipelining.html redis是一个cs模式的tcp server,使用和http类似的请求响应...
  • abc86319253
  • abc86319253
  • 2015年04月27日 12:09
  • 2762

Redis基本使用

1. Redis是什么、特点、优势 Redis是一个开源的使用C语言编写、开源、支持网络、可基于内存亦可持久化的日志型、高性能的Key-Value数据库,并提供多种语言的API。 它通常被称为 数据...
  • softwave
  • softwave
  • 2016年04月07日 11:07
  • 2491

Redis命令执行全过程

这个问题说简单也很简单,无非就是客户端发送命令请求,服务器读取命令请求,然后是命令执行器查找命令实现,执行预备操作,调用命令实现函数,执行后续工作。 但是我们想要了解的不能简简单单的就是这些。下面我...
  • zhaozonglu
  • zhaozonglu
  • 2015年07月25日 16:16
  • 927

redis学习二,redis的五种基本数据类型

redis基本数据类型 redis一共分为5中基本数据类型:String,Hash,List,Set,ZSet 第一种String String类型是包含很多种类型的特殊类型,并且是二进制安全的。比如...
  • a347911
  • a347911
  • 2017年01月04日 17:14
  • 1245

Redis的基本操作及其常用命令

一: Redis介绍 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redi...
  • qq_16619037
  • qq_16619037
  • 2016年02月18日 16:36
  • 2708
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Redis服务端执行命令基本流程
举报原因:
原因补充:

(最多只允许输入30个字)