您的当前位置:首页正文

Redis命令处理流程

2020-11-09 来源:吉趣旅游网

关键数据结构和方法 1) struct redisCommand redisCommandTable 位于redis.c:115 2) processCommand 位于redis.c:1653 redisCommand数据结构 struct redisCommand { char *name; redisCommandProc *proc; int arity; char *sflags; /* Flags as string rep

关键数据结构和方法

1) struct redisCommand redisCommandTable 位于redis.c:115 2) processCommand 位于redis.c:1653

redisCommand数据结构

struct redisCommand {
 char *name;
 redisCommandProc *proc;
 int arity;
 char *sflags; /* Flags as string representation, one char per flag. */
 int flags; /* The actual flags, obtained from the 'sflags' field. */
 /* Use a function to determine keys arguments in a command line. */
 redisGetKeysProc *getkeys_proc;
 /* What keys should be loaded in background when calling this command? */
 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 */
 long long microseconds, calls;
};

对比某一个记录看一下字段的含义,也学习一下如何设计一个好的命令协议。 {"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
{"set",setCommand,-3,"wm",0,noPreloadGetKeys,1,1,1,0,0},
最前面的name和proc是最容易也是最关键的,表示一个名字对应的处理函数。 arity表示参数的个数,如果是负数,则表示 最少n个参数,如果是正数字,则表示必选是n个参数; sflag表示该命令的属性,从populateCommandTable(redis.c:1445)中可以得出属性列表为:
 * w: write command (may modify the key space).
 * r: read command (will never modify the key space).
 * m: may increase memory usage once called. Don't allow if out of memory.
 * a: admin command, like SAVE or SHUTDOWN.
 * p: Pub/Sub related command.
 * f: force replication of this command, regardless of server.dirty.
 * s: command not allowed in scripts.
 * R: random command. Command is not deterministic, that is, the same command
 * with the same arguments, with the same key space, may have different
 * results. For instance SPOP and RANDOMKEY are two random commands.
 * S: Sort command output array if called from script, so that the output
 * is deterministic.
 * l: Allow command while loading the database.
 * t: Allow command while a slave has stale data but is not allowed to
 * server this data. Normally no command is accepted in this condition
 * but just a few.
 * M: Do not automatically propagate the command on MONITOR.

redisGetKeysProc以及后续的参数是处理参数列表,从命令行中解析出那些是key那些是value。 firstkey ,lastkey ,keystep分别表示key是从哪个位置到哪个位置,间隔是多少。典型的比如 set name 'aa' ,则key是从1到1,间隔也是1。 sdiff key1 key2 ,则lastkey设置为-1表示,后面所有的都是key mset k1 'a' k2 'b' 则keysttep=2则表示,每隔一个参数为key
通过这三个参数可以表示出一些固定的,但是很难表示如下命令格式 COMMAND key value key value value key value value value 因为key没有规律。

设计一个自己的命令

在系统中,已经存在一个time命令,但是返回的是秒数和毫秒。假设我们希望返回服务端的易读懂的时间,并且根据传入的参数返回时间的格式。
1) 在redisCommandTable中增加一条记录 {"utime",utimeCommand,-1,"r",0,NULL,0,0,0,0,0}
2)在redis.h增加函数声明: void utimeCommand(redisClient * c); 3)在redis.c增加实现函数:
void utimeCommand(redisClient *c) {

	char * fmt = c->argv[1]->ptr;
	char fmtResult[64];
	memset(fmtResult,0,64);
	
	struct timeval tv;
	gettimeofday(&tv,NULL);
	struct tm	*tm;
	tm = localtime(&tv.tv_sec);
	if(tm!=NULL){
	strftime(fmtResult, sizeof fmtResult, fmt, tm);
 
	}else{
	sprintf(fmtResult,"%s","error when retriving time");
	}

	addReplyBulkCString(c,fmtResult);	

}

\
显示全文