preface

In the last article, we looked at the event mechanism of Redis6, and the event handling mechanism hasn’t changed much since the previous version. In version 6.0, the biggest change is to add multithreaded IO mechanism, effectively improve Redis in the processing of network IO processing capacity, official claims that the performance can be improved to double, I did not make a specific performance test, you can reference: Redis6.0 multithreaded performance test. Let’s explore the specific process of multithreaded IO implementation from the source code.

Event mechanism review: Redis6.0 event mechanism detailed explanation

Multithreaded design

Redis6.0 multithreading is divided into the following parts:

  1. inserver.cSet in thebeforesleepCallback function, file event callback function and other related Settings, wherebeforesleepSome of the more important ones arehandleClientsWithPendingReadsUsingThreads“, which will be described in detail below
  2. Start the IO Thread and set the handler for the IO Thread
  3. Event polling is performed to distribute IO events to different threads for processing

The overall structure is shown in the figure below:

Source code process analysis

Set the event handler

Call initServer > aeSetBeforeSleepProc set beforesleep function, including handleClientsWithPendingReadsUsingThreads all IO thread to read status, The function source code is as follows:

Start multithreading

initThreadedIO

InitServerLast() -> initThreadedIO(); InitServerLast() -> initThreadedIO();

Redis 6.0 allows up to 128 I/O threads to be started. When redis 6.0 starts, each io_threads_list is initialized as a bidirectional linked list, which is used to store task information, and the callback function IOThreadMain is registered for I/O threads. Let’s go through the process together.

IOThreadMain

IOThreadMain callback processing procedure is relatively simple, is a sign of according to the current task (read | write), traversing task list processing operations on a mission.

The redis I/O thread can only handle read or write operations at the same time. The redis I/O thread can only handle reads and writes at the same time. ReadQueryFromClient () ¶ readQueryFromClient ();

So far and multi-threaded start related source execution process has been analyzed, the completion of the service start into the time polling.

Event polling

The main thread calls aeMian -> aeProcessEvents, and the redis service starts to accept and process events. Beforesleep and Aftersleep hook functions are executed during poll execution. If we have plugin requirements, we can use them. There are two of the more important function in beforesleep handleClientsWithPendingWritesUsingThreads and handleClientsWithPendingReadsUsingThreads, Clients_pending_read and server.clients_pending_write are processed before the next batch training to ensure that there are no more tasks to be processed in the list.

Read the event callback: including acceptTcpHandler | acceptTLSHandler | acceptUnixHandler | moduleBlockedClientPipeReadable underlying call acceptCommonHandler -> createClient -> connSetReadHandler(conn, readQueryFromClient) Sets the read event handler for the connection.

Thus combed the whole line is completed, the client connect to read | write event arrives, the callback function to add events to the server. The clients_pending_read and server clients_pending_write, The IO thread then polls to process wait events for each client, and then goes to the next poll.

conclusion

Summary is not easy, do not forget the quality of three consecutive, the next phase of the study of the object structure and data structure of the service, I beg you to see a small praise 🙂