Document directory
- Connection Establishment
- Server processing sequence
- Maxclients
- Output buffer size limit
- Input buffer size limit
- Client timeout
This article describes some internal implementation mechanisms for redis to process client connections, including connection processing, timeout, and buffer.
Note: The content described in this article is based on redis2.6 and later versions.
Connection Establishment
Redis listens to a TCP port or UNIX socket to receive connections from clients. After a connection is established, redis performs the following operations internally:
- First, the client socket is set to non-blocking mode because redis adopts the non-blocking multiplexing model for network event processing.
- Then set the tcp_nodelay attribute for the socket to disable the Nagle algorithm.
- Then create a readable file event to listen to the data sent from the client socket.
After the client connection is initialized, redis will view the current number of connections, and then compare the configured maxclients value. If the current number of connections has reached the maximum number of connections, the connection cannot be received, redis will directly return a client connection error and immediately close the connection.
Server processing sequence
If multiple clients connect to redis and send commands to redis, which client will the redis server first process? The answer is not sure, mainly due to two factors. One is the size of the number of the socket corresponding to the client, and the other is the sequence in which the kernal reports events of each client.
The steps for redis to process data sent from a client are as follows:
- It calls read () for the socket that triggers the event and reads only once (instead of reading the message on the socket) to prevent the client from sending too many commands continuously, in this case, requests from other clients cannot be processed for a long time.
- Of course, after this read () call is complete, no matter how many commands it contains, It will be executed in one order. In this way, the client commands are treated fairly.
Maxclients
In redis2.4, the maximum number of connections is directly hardcoded in the Code, and in version 2.6 this value becomes configurable. The default value of maxclients is 10000. You can also modify this value in redis. conf.
Of course, this value is only a wishful thinking value of redis. redis will also take care of the system's limit on the number of file descriptors used by processes. At startup, redis checks the soft limit of the system to check the maximum number of opened file descriptors. If the number set by the system is smaller than the number we want to add 32 to the maximum number of connections, the setting of this maxclients will not work, and redis will set this value as required by the system. (ADD 32 because redis uses a maximum of 32 file descriptors internally, so the connection can use equal to any descriptive symbols that can be used minus 32 ).
When this happens (maxclients does not work after it is set), there will be corresponding logs during redis startup. For example, if the following command is used to set the maximum number of clients to 100000, redis needs 100000 + 32 file descriptors, and the maximum file descriptor of the system is set to 10144, therefore, redis can only set maxclients to 10144-32 = 10112.
$ ./redis-server --maxclients 100000[41422] 23 Jan 11:28:33.179 # Unable to set the max number of files limit to 100032 (Invalid argument), setting the max clients configuration to 10112.
So when you want to set the maxclients value, it is best to modify your system settings by the way. Of course, you can also find this problem when reading logs.
The specific setting method depends on your individual needs. You can modify the limits of the current session, or directly modify the default settings of the system through sysctl. For example:
Ulimit-Sn 100000 # this will only work if hard limit is big enough.
Sysctl-W fs. File-max = 100000
Output buffer size limit
For redis output (that is, the return value of a command), its size is often uncontrollable. It may be a simple command that can generate a large volume of returned data. In addition, because too many commands are executed, the returned data rate exceeds the sending rate to the client. In this case, message accumulation occurs, resulting in an increasing output buffer, excessive memory usage, or even system crashes.
Therefore, redis sets some protection mechanisms to avoid this situation. These mechanisms act on different types of clients and have different output buffer size restrictions. There are two restrictions:
- One is the size limit. When the buffer of a client exceeds a certain hour, the client connection is closed directly.
- In addition, when the buffer of a client takes up too much space for a period of time, the client connection is also closed directly.
The policies for different clients are as follows:
- For common clients, the limit is 0, that is, no limit, because common clients usually adopt a blocking message response mode, such as sending a request, waiting for a return, and then sending a request, wait for the response. This mode usually does not cause the accumulation of the output buffer to expand.
- For pub/sub clients, the size limit is 32 MB. When the output buffer exceeds 32 MB, the connection is closed. The persistent limit is that when the client buffer size exceeds 8 m for 60 seconds, the connection will also be closed.
- For the slave client, the size limit is 256 MB, and the persistent limit is to close the connection when the client buffer size exceeds 64 MB for 60 seconds.
The above three rules are configurable. You can use the config set command or modify the redis. conf file.
Input buffer size limit
Redis imposes a violent limit on the size of the input buffer. When the size of the request transmitted by the client exceeds 1 GB, the server will directly close the connection. This method can effectively prevent some input buffer problems caused by client or server bugs.
Client timeout
For the current redis version, the server does not close idle clients for a long time by default. However, you can modify the default configuration to set the expected timeout value. For example, if the client does not interact for a long time, it will be closed directly. Similarly, you can use the config set command or modify the redis. conf file.
It is worth noting that the timeout setting only works for common clients. For pub/sub clients, the long-term idle status is normal.
In addition, the actual timeout time may not be as accurate as set, because redis does not use a timer or round-training Traversal method to detect client timeout, instead, you can perform a step-by-step check. The result is that the timeout value may be set to 10 seconds, but the actual execution time is 12 seconds before the client is closed.
Client Command
Redis client commands can implement three functions: Check the connection status, kill a connection, and set a name for the connection.
The client list command can be used to obtain the status of all current clients as follows:
redis 127.0.0.1:6379> client listaddr=127.0.0.1:52555 fd=5 name= age=855 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=clientaddr=127.0.0.1:52787 fd=6 name= age=6 idle=5 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
As shown in the output of the above command, redis currently has two clients connected, each line represents the information of a connection:
- ADDR: the TCP address of the client, including the IP address and port
- FD: file descriptor handle number corresponding to the client connection socket
- Name: name of the connection. It is null by default and can be set through client setname
- Age: number of seconds after the client is alive
- Idle: number of seconds when the client is idle
- Flags: client type (n indicates a common client, for more types, see http://redis.io/commands/client-list)
- Omem: size of the output buffer
- CMD: name of the last command to be executed
You can view the client list document to view the meaning of all outputs.
After obtaining the client list through the above command, you can use the client kill command to kill the specified connection. The client kill parameter is the above ADDR value.
As mentioned above, the client setname and client getname can be used to set a name for a connection.
Reference Source: http://redis.io/topics/clients http://blog.nosqlfan.com/html/4153.html