Redis is the remote dictionary service. It is an open source log-type Key-Value database written in ANSI C language, supports the network, can be based on memory and can be persisted, and provides multiple language API.
(Learning video sharing: redis video tutorial)
File event processor
Redis has developed a network event processor based on the Reactor mode. This processing The handler is called a file event handler. Its structure is composed of 4 parts: multiple sockets, IO multiplexer, file event dispatcher, and event processor. Because the consumption of the file event dispatcher queue is single-threaded, Redis is called a single-threaded model.
Message processing process
The file event processor uses I/O multiplexing (multiplexing) procedures to listen to multiple sockets at the same time, and Different event handlers are associated with the socket based on the task it is currently performing.
When the monitored socket is ready to perform operations such as connection response (accept), read (read), write (write), close (close), etc., the file event corresponding to the operation is will occur, then the file event handler will call the event handler previously associated with the socket to handle these events.
Although multiple file events may occur concurrently, the I/O multiplexer will always push all sockets that generate events into a queue, and then pass through this queue to Send sockets to the file event dispatcher sequentially, synchronously, one socket at a time: when the event generated by the previous socket is processed (the socket is the object of the event) The associated event handler is executed), and the I/O multiplexer will continue to send the next socket to the file event dispatcher.
I/O multiplexing program implementation
All functions of Redis's I/O multiplexing program are packaged by selecting, epoll, evport and kqueue. It is implemented by multiplexing function library. Each I/O multiplexing function library corresponds to a separate file in the Redis source code, 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 in the figure below.
For a detailed explanation of epoll, you can click to view and thoroughly understand the principle of efficient operation of epoll
The role of Redis in I/O multiplexing programs The #include macro is used to define corresponding rules in the implementation source code. The program will automatically select the best-performing I/O multiplexing function library in the system during compilation as the underlying implementation of the Redis I/O multiplexing 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
The I/O multiplexer can listen to the ae.h/AE_READABLE event and ae.h/AE_WRITABLE event of multiple sockets. The correspondence between class 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 there is a new When an acceptable socket appears (the client performs a connect operation on the server's listening socket), the socket generates an AE_READABLE event.
When the socket becomes writable (the client performs a read operation on the socket), the socket generates the AE_WRITABLE event. The I/O multiplexer allows the server to listen to the AE_READABLE event and the AE_WRITABLE event of the socket at the same time. If a socket generates both events at the same time, the file event dispatcher will prioritize the AE_READABLE event and wait until the AE_READABLE event is processed. After that, handle the AE_WRITABLE event. This means that if a socket is both readable and writable, the server will read from the socket first and then write to the socket.
File event processor
Redis has written multiple processors for file events. These event processors are used to implement different network communication requirements. 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 with the listening socket.
In order to receive command requests from the client, the server must associate the command request handler with the client socket.
In order to return the execution result of the command to the client, the server must associate the command reply processor with the client socket.
Connection 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. The specific implementation is as follows A wrapper for the sys/socket.h/accept function.
When the Redis server is initialized, the program will associate this connection response processor with the AE_READABLE event of the server listening socket. When a client uses the sys/socket.h/connect function to connect to the server listening socket When , the socket will generate an AE_READABLE event, triggering the connection response processor to execute, and perform the corresponding socket response operation, as shown in the figure.
Command request processor
The readQueryFromClient function in networking.c is the command request processor of Redis. This processor is responsible for reading from the socket. The content of the command request sent by the client is specifically implemented as a wrapper of the unistd.h/read function.
When a client successfully connects to the server through the connection response processor, the server will associate 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 an AE_READABLE event, triggering the command request processor to execute, and perform the corresponding socket read operation, as shown in the figure.
#During the entire process of the client connecting to the server, the server will always associate the command request processor for the AE_READABLE event of the client socket.
Command reply processor
The sendReplyToClient function in networking.c is the command reply processor of Redis. This processor is responsible for returning the command reply obtained by the server after executing the command to the client through the socket. end, which is specifically implemented as a wrapper for the unistd.h/write function.
When the server has a command reply that needs 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, triggering the execution of the command reply processor, and performing the corresponding socket write operation, as shown in the figure.
When the command reply is sent, the server will disassociate the command reply processor from the AE_WRITABLE event of the client socket.
A complete client-server connection event example
Assuming that the Redis server is running, then the AE_READABLE event of the listening socket of this server should be in the listening state, and this event The corresponding processor 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 connection response processor to execute: the processor will respond to the client's connection request, and then create The client socket, as well as the client status, and associates the AE_READABLE event of the client socket with the command request processor so that the client can send command requests 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 execution of the command request processor. The processor reads the client's command content and then passes it to the relevant program. to execute.
Executing commands will generate corresponding command replies. In order to transmit these command replies back to the client, the server will associate the AE_WRITABLE event of the client socket with the command reply processor: when the client attempts to read When the command replies, the client socket will generate an AE_WRITABLE event, triggering 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 of the client socket. Association between events and command reply handlers.
Related recommendations: redis database tutorial
The above is the detailed content of Why is redis said to be single-threaded?. For more information, please follow other related articles on the PHP Chinese website!