所谓的redis的管道就是redis针对批处理数据的一种技术。
我们正常的操作是: 请求--网络IO--redis响应--网络IO--答复
通过管道pipLined后相当于跟redis服务端建立了一个通道,不是每个访问的数据都走上边的正常流程,而是将一批数据塞到管道中一次性发送给redis服务端,这样的好处是极大的减少了网络IO的耗时,从而提高了效率。
管道在关闭之前或者说在数据未完全访问完之前,已经处理过的数据将存于内存之中,等这批数据完全处理完之后再将结果返回,由此可见在大批量数据的情况下还是比较消耗内存的。
使用如下:
public Set<String> getByPipline(Jedis jedis,Set<String> keys){ //获取pipline管道 Pipeline pipeline = jedis.pipelined(); Iterator<String> key = keys.iterator(); Set<String> result = new HashSet<String>(); //管道返回的结果集 List<Response<Set<String>>> searchResult = new ArrayList<Response<Set<String>>>(); while (key.hasNext()){ //每一个key的结果 searchResult.add(pipeline.smembers(key.next())); } pipeline.sync(); if (result.size() >0){ for (Response<Set<String>> keyResult:searchResult) { //从结果集中获取需要的value的数据 result.addAll(keyResult.get()); } } return result; }
大家都说sync()这个方法很重要,它到底做了什么,看下源码:
public void sync() { if (this.getPipelinedResponseLength() > 0) { List<Object> unformatted = this.client.getAll(); Iterator var2 = unformatted.iterator(); while(var2.hasNext()) { Object o = var2.next(); this.generateResponse(o); } } }
protected Response<?> generateResponse(Object data) { Response<?> response = (Response)this.pipelinedResponses.poll(); if (response != null) { response.set(data); } return response; //这就是我们需要的返回的值 }
总之:pipline为我们提供了批处理,极大的减少了网络开销,从而提高了redis的性能,从过你的代码中还在for循环中调用redis不断的读写操作,是时候考虑下pipline了。