Redis is a CS-mode TCP server that uses a request-response protocol similar to HTTP. A client can initiate multiple request commands from a single socket connection. After each request command is issued, the client usually blocks and waits for the Redis service to process, and the result is returned to the client via a response message after Redis finishes processing the request. 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
Basically four commands require 8 TCP messages to complete. Due to the network latency of the communication, the packet transfer time between the client and server takes 0.125 seconds. Then the above four commands 8 messages will take at least 1 seconds to complete. This way, even though Redis can handle 100 commands per second, our client can only issue four commands in a second. This shows that the processing power of Redis is not fully utilized. In addition to commands that can handle multiple keys with a single command such as Mget,mset
We can also use pipeline to send multiple commands from the client, without waiting for the response of a single command to return, and the Redis server will package the results of multiple commands together and return them to the client. 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
Assume that the TCP message is not split because it is too long. Possibly two TCP messages can complete four commands, the client can put four INCR command to send a TCP message together, the server can put the processing results of four commands to a TCP message return. By pipeline mode when there is a large amount of operation. We can save a lot of time originally wasted on network latency. Note that the pipeline Package command is sent, and Redis must cache all command processing results before all commands are processed. The more commands are packaged, the more memory is consumed by the cache. So the more you pack the more commands the better. Specific how much appropriate needs to be tested according to the specific situation. The following is a test of a Jredis client using pipeline
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
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 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 jredis =
new JRedisPipelineService(spec);
for (
int i =
0
; i <
100000
; i++) {
jredis.incr(
"test2"
);
}
jredis.quit();
}
catch (Exception e) {
}
}
}
|
Output
103408//Use of pipeline
104598//Not used
The test result is not very obvious, it should be related to my test environment. I am Linux on my own win connection virtual machine. Network latency is relatively small. So pipeline
Advantage is not obvious. If the network latency is small, it is best not to pipeline. In addition to increasing complexity, the performance gains are not obvious.
Redis Data Summary (v) Redis pipeline