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服务端

  • 2017-04-27 09:34
  • 601KB
  • 下载

32位redis服务端和客户端

  • 2016-03-13 21:26
  • 917KB
  • 下载

Redis服务端配置总结

1、redis 确保读到配置文件,使用下面方式启动服务器: #./redis-server/path/redis.conf   2、默认接受连接的端口 #6379   3、最大listen 队列 #t...

redis服务端和客户端

  • 2017-01-05 18:17
  • 7.34MB
  • 下载

Redis服务端的配置(单机+集群)

Linux下安装 Redis 1、wget http://download.redis.io/redis-stable.tar.gz 2、tar xvzf redis-stable.tar.gz 3...

Linux redis服务基本配置操作

Redis的安装和部署 基本知识 1、Redis的数据类型:   字符串、列表(lists)、集合(sets)、有序集合(sorts sets)、哈希表(hashs) 2、Re...
  • io_01
  • io_01
  • 2017-03-31 11:27
  • 97

redis服务日常维护命令

包括:redis服务启动命令,Redis-cli命令最新总结,Redis的“死键”问题,常用架构

Redis教程3(Redis服务启动停止,命令客户端的使用)

Note:建议在开发环境中在使用windows下的redis,如果在正式

redis 学习手册之redis服务操作命令

针对redis服务器来操作的命令,比如查看服务器统计信息,备份, 安全设置等等。

在windows上部署redis服务,以及使用jedis客户端。

一、 server端安装 1、下载 https://github.com/MSOpenTech/redis 截止发稿之日,最新的版本是2.8 点击页面最右侧的Download ZIP按钮,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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