Redis-Redis threading model (graphic)

Redis thread model

File event handler

Redis developed a network event processor based on the Reactor model. This processor is called a file event processor. It is composed of 4 parts: multiple sockets, IO multiplexing program, file event dispatcher, and event handler. Because the consumption of the file event dispatcher queue is single-threaded, Redis is called the single-threaded model.
Insert picture description here

Message processing flow

  • The file event handler uses an I/O multiplexing program to monitor multiple sockets at the same time, and associates different event handlers for the sockets according to the tasks currently performed by the sockets.
  • When the monitored socket is ready to perform connection response (accept), read (read), write (write), close (close) and other operations, the file event corresponding to the operation will be generated, and then the file The event handler will call the event handler associated with the socket to handle these events.

Although multiple file events may appear concurrently, the I/O multiplexing program always pushes all event-generating sockets into a queue, and then through this queue, in order (sequentially), Synchronously, one socket at a time, the socket is sent to the file event dispatcher: when the event generated by the previous socket is processed (the socket is executed by the event handler associated with the event Finish), the I/O multiplexing program will continue to send the next socket to the file event dispatcher.

The realization of I/O multiplexing program

All functions of Redis's I/O multiplexing program are realized by packaging select, epoll, evport and kqueue I/O multiplexing function libraries. Each I/O multiplexing function library is in Redis The source code corresponds to a separate file, such as ae_select.c, ae_epoll.c, ae_kqueue.c, etc.

Because Redis implements the same API for each I/O multiplexing function library, the underlying implementation of the I/O multiplexing program is interchangeable. As shown
Insert picture description here
in the figure below, Redis is in I/O multiplexing The implementation of the multiplexing program uses the #include macro to define the corresponding rules in the source code, and the program will automatically select the I/O multiplexing function library with the best performance in the system as the I/O multiplexing of Redis during compilation. The underlying implementation of the program:

/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
        #ifdef HAVE_KQUEUE
        #include "ae_kqueue.c"
        #else
        #include "ae_select.c"
        #endif
    #endif
#endif

Types of file events

I/O multiplexing programs can monitor the ae.h/AE_READABLE events and ae.h/AE_WRITABLE events of multiple sockets. The correspondence between these two types of events and socket operations is as follows:

  • When the socket becomes readable (the client performs a write operation on the socket, or performs a close operation), or when a new acceptable socket appears (the client-to-server listening socket Perform connect operation), the socket generates an AE_READABLE event
  • When the socket becomes writable (the client performs a read operation on the socket), the socket generates an AE_WRITABLE event. The I/O multiplexing program allows the server to listen to the AE_READABLE event and AE_WRITABLE event of the socket at the same time. If a socket generates these two events at the same time, the file event dispatcher will give priority to the AE_READABLE event and wait until the AE_READABLE event is processed. After that, the AE_WRITABLE event is processed. This means that if a socket is both readable and writable, the server will read the socket first, and then write the socket.

File event handler

Redis has written multiple processors for file events. These event processors are used to implement different network communication requirements. The commonly used processors are as follows:

  • In order to respond to each client connected to the server, the server must associate a connection response processor for the listening socket.
  • In order to receive the command request from the client, the server must associate a command request processor for the client socket.
  • In order to return the execution result of the command to the client, the server must associate the command reply processor for the client socket.

Connect response processor

The acceptTcpHandler function in networking.c is the connection response processor of Redis. This processor is used to respond to the client connecting to the server's listening socket, and is implemented as a wrapper of the sys/socket.h/accept function.

When the Redis server is initialized, the program associates the connection response processor with the AE_READABLE event of the server's listening socket. When a client connects to the server's listening socket with the sys/socket.h/connect function, The socket will generate an AE_READABLE event, trigger the connection response processor to execute, and perform the corresponding socket response operation, as shown in the figure.
Insert picture description here

Command request handler

The readQueryFromClient function in networking.c is the Redis command request processor. This processor is responsible for reading the command request content sent by the client from the socket, which is specifically implemented as a package of the unistd.h/read function.

When a client successfully connects to the server through the connection response processor, the server associates the AE_READABLE event of the client socket with the command request processor. When the client sends a command request to the server, the socket will Generate the AE_READABLE event, trigger the command to request the processor to execute, and perform the corresponding socket read operation, as shown in the figure.
Insert picture description here
During the entire process of the client connecting to the server, the server will always request the processor for the AE_READABLE event associated command of the client socket.

Command reply processor

The sendReplyToClient function in networking.c is the Redis command reply processor. This processor is responsible for returning the command reply obtained after the server executes the command to the client through the socket, which is implemented as a package of the unistd.h/write function.

When the server has a command reply to be sent to the client, the server will associate the AE_WRITABLE event of the client socket with the command reply processor. When the client is ready to receive the command reply from the server, the AE_WRITABLE event will be generated , Trigger the execution of the command reply processor and execute the corresponding socket write operation, as shown in the figure.
Insert picture description here
When the command reply is sent, the server will disassociate the command reply processor and the AE_WRITABLE event of the client socket

An example of a complete client-server connection event

Assuming that the Redis server is operating, the AE_READABLE event of the listening socket of this server should be in the listening state, and the processor corresponding to the event is the connection response processor.

If a Redis client initiates a connection to the Redis server at this time, the listening socket will generate an AE_READABLE event, triggering the execution of the connection response processor: the processor will respond to the client's connection request, and then create a client socket, And the client state, and associate the AE_READABLE event of the client socket with the command request processor, so that the client can send a command request to the main server.

After that, the client sends a command request to the Redis server, then the client socket will generate an AE_READABLE event, triggering the command to request the processor to execute, the processor reads the client's command content, and then passes it to the relevant program for execution.

Executing commands will generate corresponding command replies. In order to send these command replies back to the client, the server associates the AE_WRITABLE event of the client socket with the command reply processor: when the client tries to read the command reply, the client The end socket will generate the AE_WRITABLE event, which triggers the execution of the command reply processor. When the command reply processor writes all the command replies to the socket, the server will release the AE_WRITABLE event and the command reply processor of the client socket The relationship between.
Insert picture description here

Thinking problem

Q:
Why is Redis's single-threaded model so efficient?
A:

  1. Pure memory access: Data is stored in memory, and the response time of the memory is about 100 nanoseconds. This is an important basis for Redis's trillion-level access per second.
  2. Non-blocking I/O: Redis uses epoll as the implementation of I/O multiplexing technology, and Redis’s own event processing model converts the connection, reading, writing, and closing of epoll into time, not I/O Too much time was wasted.
  3. Single thread avoids the consumption of thread switching and race conditions.
  4. Redis uses a single-threaded model. If each command takes a lot of time to execute, it will cause other threads to block, which is fatal for high-performance services like Redis, so Redis is a database for high-speed execution.

The content is organized by referring to online articles, only for personal learning use:

  1. https://www.jianshu.com/p/6264fa82ac33
  2. https://blog.csdn.net/m0_37524661/article/details/87086267

Guess you like

Origin blog.csdn.net/magentodaddy/article/details/108532361