Hello everyone, my name is Qixi (xī).
Everyone is familiar with Redis, but it is easy to be ignored when it is invisible at the usage level. What I want to share with you today is the role of each buffer in , the consequences of overflow and the direction of .
Before starting the text, I want to say a few more words. Whether it is Redis or other middleware, many underlying principles are similar, and the design ideas are universal.
If you are learning new frameworks/components in the future, you can try to associate with the knowledge points you have already learned, so that it will be easier to understand and not to say rote memorization.
For example, what is the purpose of the buffer now mentioned?
Without it, for performance.
Either cache data, improves response speed . For example, there is a change buffer in MySQL
Or worry that the speed of consumers can't keep up with production, or data loss . Therefore, the production data needs to be temporarily stored. This is what Redis' buffers do.
In addition, the consumer's speed can't keep up. If it is processed synchronously, will it also slow down the producer, so the speed of the producer is also guaranteed here.
Some readers may say: nonsense, consumers can't keep up, what's the use of producers?
In fact, is there a possibility that the producer does not care when the consumer uses it? The former is responsible for processing what the latter needs and giving it to it. The producer is very busy, and there is a lot of other data to process, so it is not possible to wait for the consumer to finish synchronous consumption before doing other things.
It seems that the beginning of the expansion is a bit more, I will close it, and I will talk about it in detail below. If you have any doubts, please get on the bus, Qixi officially departs.
1. Each buffer
First of all, what buffer does Redis have?
4 in total:
- client input buffer
- client output buffer
- copy buffer
- Copy backlog buffer
2. Client input buffer
The server will set an input buffer for each connected client
2.1 Function
Staging request data.
The input buffer will temporarily store the commands sent by the client, and the Redis main thread will read the commands from the input buffer and process them.
In order to avoid mismatches between client and server request sending and processing speeds, this is the same as the output buffer to be discussed later.
2.2 Overflow scenarios
First of all, the buffer is a fixed-size memory area. If this place is to be filled, Redis will directly close the client connection.
Protect yourself, it is better for your client to hang up than my server to hang up. Once the server hangs up, all clients are useless.
There are two situations when the buffer is filled up:
- or fill up at once
- Either the production rate is faster than the consumption rate, and it is slowly filled up
Then the above principle corresponds to the Redis scenario.
The situation of filling up all at once can be writing a large amount of data into Redis, which is on the order of millions.
Another situation can be that the Redis server is blocked due to time-consuming operations, resulting in the inability to consume the input buffer data.
2.3 Optimization
Corresponding to the above two overflow scenarios, the optimization direction is natural.
In the case of filling up all at once, is it possible to consider not to write so much data all at once, and whether to remove the data (in fact, it is unreasonable to write a large amount of data all at once)
Also, is it possible to increase the buffer size?
This is actually not possible, because there is no place to set it. Currently, the default size of the input buffer allocated by the server for each client is 1GB.
Then it's the second overflow scenario: the processing speed on both sides is inconsistent.
Normally, the server should not be blocked for a long time, so you need to see what caused the blocking and solve it.
3. Client output buffer
The same as the input buffer, the server will
3.1 Function
Same as above, but also temporarily store request data.
In this place, I actually said at the beginning of the article that the producer does not care when the consumer uses it, and is only responsible for processing the things the consumer requested before.
It may be a bit abstract, I understand it like this, if there is something wrong, please leave a message to correct me
The server is generally connected to multiple clients, and the redis network communication module is single-threaded (even if the new version supports multi-threading)
What if there is no output buffer?
The server has processed many requests from client A, and it needs to go through the time-consuming operation of the network and return it to client A. During this process, client B's request has not been processed and responded to by the server, so the throughput cannot go up.
With the buffer, at least the server can be freed to handle client B's request.
3.2 Overflow scenarios
This is also the same as the input buffer, so I won't be verbose. If it overflows, the server will also close the client connection.
- The server side returned a lot of data, which filled up all at once
- The speed of returning data is too fast, such as executing the MONITOR command, it will continue to output the monitored command operations
- The buffer size is set unreasonably.
3.3 Optimization
Similarly, don't read large amounts of data at once; don't continuously execute MONITOR commands on the wire.
The size of the output buffer can be set by client-output-buffer-limit.
But in general, we don't need to change it, because the default is enough, just understand it here.
It is worth mentioning that the messages of Redis publish and subscribe are also in this buffer, and client-output-buffer-limit pubsub 8mb 2mb 60
can be used to limit the size.
- pubsub means setting up the subscribing client. Change to normal to indicate that the current setting is a normal client
- The meaning of the whole configuration is: if the buffer size actually occupied exceeds 8MB, or if the amount of writing to the output buffer exceeds 2MB within 60 consecutive seconds, the server will close the client connection.
4. Copy the buffer
As a warm reminder, if you don't know about Redis synchronization/replication, such as full/incremental replication, you can read my article: This article will let you understand Redis master-slave synchronization .
Back to the topic below.
There must be master-slave replication, and data replication between master-slave includes full replication and incremental replication.
Full replication is to synchronize all data, while incremental replication only synchronizes the commands received by the master library during the network disconnection of the master and slave libraries to the slave library.
4.1 Function
Staging data.
A replication buffer is maintained on the master node for each slave node .
During full replication, the master node will continue to receive the write command request sent by the client while transferring the RDB file to the slave node, and save it in the replication buffer. After the RDB file transfer is completed, it will be sent to the slave node for execution. .
4.2 Overflow scenarios
Receiving and loading RDBs from the slave node is slow, and the master node receives a large number of write commands. The write commands will accumulate in the replication buffer and eventually overflow.
Once it overflows, the master node will directly close the connection with the slave node for the replication operation, resulting in the failure of full replication.
4.3 Optimization
The data volume of the master node can be controlled between 2~4GB (for reference only), which can make the full synchronization execute faster and avoid the accumulation of too many commands in the copy buffer.
You can also adjust the buffer size, or the previous client-output-buffer-limit
parameter.
For example: `
config set client-output-buffer-limit slave 512mb 128mb 60`
- The slave parameter indicates that the configuration item is for the replication buffer.
- The meaning of the whole configuration is: if the buffer size actually occupied exceeds 512MB, or if the amount of writing to the output buffer exceeds 128MB within 60 consecutive seconds, the server will close the synchronous connection.
5. Copy the backlog buffer
This is the buffer used in the new copy.
For the specific introduction, it is recommended to read the article mentioned above. I have written 2k+ words here, and I can't stand it.
5.1 Function
Staging data.
After the slave node is disconnected unexpectedly and reconnects, it can retrieve the data that was not synchronized during the synchronization from this buffer.
5.2 Overflow scenarios
Will not overflow. (Can't think of it.jpg)
The buffer is essentially a fixed-length, first-in, first-out queue , the default is 1MB.
So when the queue is full, it is not an error, nor is the connection directly closed like the above buffers. Instead, it overwrites the data that entered the queue earliest.
Therefore, if there are slave nodes that have not synchronized these old command data, it will cause the master and slave nodes to re-do full replication instead of incremental replication.
PS: The performance overhead of full replication is much greater than incremental replication
5.3 Optimization
Adjust the size of the copy backlog buffer, the parameters are: repl_backlog_size
Originality is not easy. If you think the article is good, I hope you can pay attention to my public account: is learning Java , the article is the first public account.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。