Redis is a CS-mode TCP server that uses a request response protocol similar to HTTP. A client can initiate multiple request commands through a socket connection. After each request command is sent, the client usually blocks and waits for the redis service to process it. After redis completes processing, the Request command returns the result to the client through the Response Message. The basic communication process is as follows:
Client: incr x
Server: 1
Client: incr x
Server: 2
Client: incr
X
Server: 3
Client: incr x
Server: 4
Based on the above four commands, eight TCP packets are required. Due to network latency, it takes 0.125 seconds to transmit packets from the client to the server. It takes at least one second to complete the above four messages. In this way, even if redis can process 100 commands per second, our client can only issue four commands in one second. This shows that redis's processing capabilities are not fully utilized. In addition to using single commands such as mget and mset to process multiple keys
We can also use pipeline to Package Multiple commands from the client and send them together without waiting for the response of a single command, the redis server will pack the processing results of multiple commands and return them to the client after processing multiple commands. The communication process is as follows:
Client: incr x
Client: incr x
Client: incr x
Client: incr x
Server:
1
Server: 2
Server: 3
Server: 4
False settings are not split because the TCP packet is too long. Two TCP packets may be able to complete four commands. The client can put the four incr commands into one TCP packet for sending together, and the server can put the processing results of the four commands into one TCP packet for returning. When a large number of operations are performed through pipeline. We can save a lot of time wasted on network latency. You must note that the command is packaged and sent in pipeline mode. redis must cache the processing results of all commands before processing all commands. The more packaged commands, the more memory consumed by the cache. So isn't it possible to pack as many commands as possible. Tests are required based on actual conditions. The following is a test of using pipeline on a jredis client.
Package Jredisstudy;
Import Org. jredis. jredis;
Import
Org. jredis. connector. connectionspec;
Import
Org. jredis. Ri. alphazero. jredisclient;
Import
Org. jredis. Ri. alphazero. jredispipelineservice;
Import
Org. jredis. Ri. alphazero. Connection. defaultconnectionspec;
Public Class
Pipelinetest {
Public Static Void Main (string [] ARGs)
{
Long Start =
System. currenttimemillis ();
Usepipeline ();
Long
End =
System. currenttimemillis ();
System. Out. println (end-Start );
Start =
System. currenttimemillis ();
Withoutpipeline ();
End =
System. currenttimemillis ();
System. Out. println (end-Start );
}
Private Static Void Withoutpipeline ()
{
Try
{
Jredis =New
Jredisclient ( "192.168.56.55" , 6379 );
For ( Int I = 0; I <100000;
I ++)
{
Jredis. incr ( "Test2" );
}
Jredis. Quit ();
} Catch (Exception
E ){
}
}
Private Static Void Usepipeline ()
{
Try
{
Connectionspec spec = defaultconnectionspec. newspec ( "192.168.56.55" , 6379, 0,
Null );
Jredis = New
Jredispipelineservice (SPEC );
For ( Int I = 0; I <100000;
I ++)
{
Jredis. incr ( "Test2" );
}
Jredis. Quit ();
} Catch (Exception
E ){
}
}
}
Output
103408 // pipeline used
104598 // not used
The test results are not obvious. This should be related to my test environment. I connect to a virtual machine in windows. Low network latency. So Pipeline
The advantage is not obvious. If the network latency is small, you 'd better not use pipeline. In addition to increasing complexity, the performance improvement is not obvious.