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 {@Autowiredprivate JedisPool jedisPool;public List<Object> plGet(List<String> keys) {Jedis jedis = null;try {jedis = jedisPool.getResource();//pipe是将所有的命令组装成pipelinePipeline 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 {@Autowiredprivate RedisPipeline redisPipeline;@Autowiredprivate RedisString redisString;private static final int TEST_COUNT = 10000;@Testpublic 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的时候,依靠的是内核输入输出的缓冲区