1. 概述
一般情况下,大家使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接,这种模式是 请求-响应,请求-响应
这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为redis是单线程的,按部就班,一步一步来。
而pipeline管道改变了这种请求模式,客户端可以一次发送多个命令,无须等待服务器的返回,请求,请求,请求,响应,响应,响应
这种模式大大减少了影响性能的关键因素-网络往返时间。
2. 示例
package com.test.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import java.io.IOException;
import java.util.List;
/**
* 访问redis单机
*
*/
public class JedisSingleTest2 {
public static void main(String[] args) throws IOException {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "10.40.65.183", 6379, 3000, null);
Jedis jedis = null;
try {
//从redis连接池里拿出一个连接执行命令
jedis = jedisPool.getResource();
Pipeline pl = jedis.pipelined();
for (int i = 0; i < 10; i++) {
pl.incr("pipelineKey");
pl.set("zhansan" + i, "zhangsan");
}
//如果不需要返回值,可以使用pl.sync()
List<Object> results = pl.syncAndReturnAll();
System.out.println(results);
} catch (Exception e) {
e.printStackTrace();
} finally {
//注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (jedis != null)
jedis.close();
}
}
}
执行结果:
[11, OK, 12, OK, 13, OK, 14, OK, 15, OK, 16, OK, 17, OK, 18, OK, 19, OK, 20, OK]
注意:采用pipeline时,如果包含多个命令,其中出现某个命令执行失败,其余命令仍然会继续执行,也就是说不存在事务概念。
示例:
for (int i = 0; i < 10; i++) {
pl.incr("pipelineKey");
pl.set("zhansan" + i, "zhangsan");
//模拟管道报错,-1是个无效值
pl.setbit("zhansan", -1, true);
}
故意在执行的语句中加入会执行出错的代码,执行结果:
[21, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 22, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 23, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 24, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 25, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 26, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 27, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 28, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 29, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range, 30, OK, redis.clients.jedis.exceptions.JedisDataException: ERR bit offset is not an integer or out of range]
从结果来看,即使出现某个命令失败,后续的仍然继续执行。