PipeLine的作用是批量执行命令
redis的性能瓶颈基本上是网络
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import java.util.List;
@Component
public class RedisPipeline {
@Autowired
private JedisPool jedisPool;
public List<Object> plGet(List<String> keys) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//pipe是将所有的命令组装成pipeline
Pipeline pipelined = jedis.pipelined();
pipelined.multi();//开启事务
//。。。。。等等命令
pipelined.exec();//提交事务
for(String key:keys){
pipelined.get(key);//不是仅仅是get方法,set方法还要很多很多方法pipeline都提供了支持
}
return pipelined.syncAndReturnAll();//这里只会向redis发送一次
} catch (Exception e) {
throw new RuntimeException("执行Pipeline获取失败!",e);
} finally {
jedis.close();
}
}
public void plSet(List<String> keys,List<String> values) {
if(keys.size()!=values.size()) {
throw new RuntimeException("key和value个数不匹配!");
}
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Pipeline pipelined = jedis.pipelined();
for(int i=0;i<keys.size();i++){
pipelined.set(keys.get(i),values.get(i));
}
pipelined.sync();
} catch (Exception e) {
throw new RuntimeException("执行Pipeline设值失败!",e);
} finally {
jedis.close();
}
}
}
两者之间的性能对比
import com.msb.redis.adv.RedisPipeline;
import com.msb.redis.redisbase.basetypes.RedisString;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest
public class TestRedisPipeline {
@Autowired
private RedisPipeline redisPipeline;
@Autowired
private RedisString redisString;
private static final int TEST_COUNT = 10000;
@Test
public void testPipeline() {
long setStart = System.currentTimeMillis();
for (int i = 0; i < TEST_COUNT; i++) { //单个的操作
redisString.set("testStringM:key_" + i, String.valueOf(i));
}
long setEnd = System.currentTimeMillis();
System.out.println("非pipeline操作"+TEST_COUNT+"次字符串数据类型set写入,耗时:" + (setEnd - setStart) + "毫秒");
List<String> keys = new ArrayList<>(TEST_COUNT);
List<String> values= new ArrayList<>(TEST_COUNT);
for (int i = 0; i < keys.size(); i++) {
keys.add("testpipelineM:key_"+i);
values.add(String.valueOf(i));
}
long pipelineStart = System.currentTimeMillis();
redisPipeline.plSet(keys,values);
long pipelineEnd = System.currentTimeMillis();
System.out.println("pipeline操作"+TEST_COUNT+"次字符串数据类型set写入,耗时:" + (pipelineEnd - pipelineStart) + "毫秒");
}
}
使用pipeLine的时候,依靠的是内核输入输出的缓冲区