当前位置:网站首页>Reading redis source code (IV) command request processing flow

Reading redis source code (IV) command request processing flow

2022-06-23 02:47:00 Star sink

This article mainly introduces... From the perspective of code structure Redis Processing flow of command request .

The whole process of the server processing the client command request : The server starts listening 、 Receive command requests and parse 、 Execute command request and return command reply

In the previous article, I analyzed the startup process of the server , This article mainly introduces Redis The request processing of , This process is mainly divided into 3 Stages : Parsing command requests 、 Call the command and return the result to the client . among , The parse command request contains : Connection is established 、 Read request ; then , adopt processCommand Function to complete the command call ; Finally, the execution result is encapsulated and returned to the client user .

1. client And server Establishing a connection

This part has been established when the service is started .

2. readQueryFromClient Read request command

The entry function for parsing the client command request is readQueryFromClient(), That is to say, all requests will be executed to readQueryFromClient() In the method ,readQueryFromClient() Method from socket The read data is put into the input buffer querybuf in , It will then call processInputBuffer() Method according to RESP Protocol to parse parameters .

Redis Using custom protocols (RESP agreement ) Format to distinguish between different command requests .

【 notes : Inline command : Use spaces to separate the parameters , After the server receives the data , The command request will be parsed with a space as a parameter separator 】

【 If it is telnet No raw protocol data is sent “ * ” The leading auxiliary information indicates the number of parameters , use processInlineBuffer() The function parses the input ; Others through processMultibulkBuffer() Function analysis 】

3. processCommand Processing command requests

After parsing the parameters, we will call processCommand() Method to execute a specific command , and processCommand in , There is a lot of validation logic before processing command requests .

for example : Whether it is quit command ; Whether the order exists ; Whether the number of parameters is legal ; Whether the client has passed the authentication ; Memory limit check 、 Cluster related verification 、 Persistence related validation 、 Master-slave replication related verification 、 Publish and subscribe related validation and transaction operations

stay processCommand() Find the corresponding command according to the command name in and call the... Of the command call() Complete the specific operation ,.

void call(client *c, int flags) {
  // ...
    
  start = ustime();
  c->cmd->proc(c);  //  stay proc Call the entry function of each command in 
  duration = ustime()-start;
​
  //  After the execution of the order , If necessary , Statistics also need to be updated , Log slow queries ,AOF Persist the command request , Propagate command requests to all slave servers, etc   
  
  //  Update statistics : Current command execution time and call times 
  c->lastcmd->microseconds += duration;
  c->lastcmd->calls++;
​
  // Log slow queries 
  slowlogPushEntryIfNeeded(c,c->argv,c->argc,duration);
    
  // ...
}

4. addReply Return execution result

After the command is executed, it will call addReply() Method returns the execution result .

Redis The server returns different types of results , Different protocol formats , The client can judge the return type according to the first character of the returned result .

// For Simple Strings the first byte of the reply is "+" 
// For Errors the first byte of the reply is "-"
// For Integers the first byte of the reply is ":"
// For Bulk Strings the first byte of the reply is "$"
// For Arrays the first byte of the reply is "*"
1) State the reply , The first character is “+”;
2) Error response , The first character is “-”;
3) Integer reply , The first character is “:”;
4) Batch reply , The first character is “$”;
5) Multiple batch replies , The first character is “*”;

however , What needs to be noted here is addReply() Method simply writes the returned data to the output buffer client->buf Or output linked list client->reply in ( Usually, when caching data, you will try to cache it to buf Output buffer , If it fails, it will try to cache to again reply Output list ), The actual network sending operation is not performed .

When will this data be sent to the client ?

5. Send data to client

Redis Before each event cycle , Will call first beforeSleep() Method , The actual network sending data operation is in beforeSleep() Method .

beforeSleep() Will be in handleClientsWithPendingWrites()/handleClientsWithPendingWritesUsingThread() Middle traversal clients_pending_write Each client node in the linked list , And call writeToClient() Method to put the output buffer client->buf and client->reply Data passing socket Send to client .

It should be noted that , When the amount of returned result data is very large , function writeToClient After performing , Some data in the client output buffer or output linked list may not be sent to the client . What do you do then ? It's simple , Just add file Events , Listen to the current client socket The writable event of the file descriptor .

if (aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
   sendReplyToClient, c) == AE_ERR){
}

When the client is writable , function sendReplyToClient The rest of the data will be sent to the client .

thus , The command request is really processed .

Write IO Callback function for event :sendReplyToClient
原网站

版权声明
本文为[Star sink]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/01/202201281751521307.html