Note: After Reading redis source code analysis-protocol, I found that the author skipped some simple points, but these simple points are exactly what I didn't understand, so I made some supplements, take notes.
Version: 2.04.
1. Requests format
* Number of parameters CRLF $ length of the first parameter CRLF the length of the first parameter CRLF... $ length of the N parameter CRLF
If you type get a in redis_cli, the request after Protocol assembly is
2\r\n$3\r\nget\r\n$1\r\na\r\n
2. Process
1. readqueryfromclient reads data from Fd: nread = read (FD, C-> querybuf + qblen, readlen );
2. processinputbuffer checks whether it is a telnet request.
2.1 C-> querybuf [0] = '*' --> processmultibulkbuffer.
2.2 Telnet --> processinlinebuffer.
3. processmultibulkbuffer: parses the command and splits the parameters into C-> argc and C-> argv. argc indicates the number of parameters. argv indicates the number of parameters.
Redis_object pointer array.
4. processcommand: When redis server is started, populatecommandtable is called to convert the rediscommandtable array into a hash
Table (server. commands), lookupcommand uses key (get) to find the ing function pointer, as shown below:
struct redisCommand redisCommandTable[] = { {"get",getCommand,2,"r",0,NULL,1,1,1,0,0}, {"set",setCommand,3,"wm",0,noPreloadGetKeys,1,1,1,0,0},。。。。
5. Call (redisclient * C, int flags): Execute the command function. One of the most important calls I personally feel is C-> cmd-> proc (c ). The preceding C-> cmd = C-> lastcmd = lookupcommand (c-> argv [0]-> PTR) has assigned a rediscommand pointer to cmd. Because it is a GET command. C-> cmd-> proc (c) = getcommand (c ).
typedef void redisCommandProc(redisClient *c);struct redisCommand { char *name; redisCommandProc *proc; int arity; .. long long microseconds, calls;};
6. Go to getcommand.
void getCommand(redisClient *c) { getGenericCommand(c);}int getGenericCommand(redisClient *c) { ... if (o->type != REDIS_STRING) { addReply(c,shared.wrongtypeerr); return REDIS_ERR; } else { addReplyBulk(c,o); return REDIS_OK; }}
7. addreplybulk.
void addReplyBulk(redisClient *c, robj *obj) { addReplyBulkLen(c,obj); addReply(c,obj); addReply(c,shared.crlf);}
8. prepareclienttowrite: The write operation is forwarded to the event splitter: sendreplytoclient ,. Write the content of C-> Buf to FD.
References:
1. http://www.hoterran.info/redis_protocol <redis source code analysis-Protocol>