详解Java使用Pipeline对Redis批量读写(hmset&hgetall)
一般情况下,RedisClient端发出一个请求后,通常会阻塞并等待Redis服务端处理,Redis服务端处理完后请求命令后会将结果通过响应报文返回给Client。
感觉这有点类似于HBase的Scan,通常是Client端获取每一条记录都是一次RPC调用服务端。
在Redis中,有没有类似HBaseScannerCaching的东西呢,一次请求,返回多条记录呢?
有,这就是Pipline。官方介绍http://redis.io/topics/pipelining
通过pipeline方式当有大批量的操作时候,我们可以节省很多原来浪费在网络延迟的时间,需要注意到是用pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。
使用Pipeline在对Redis批量读写的时候,性能上有非常大的提升。
Java测试了一下:
packagecom.lxw1234.redis;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.Set;
importredis.clients.jedis.Jedis;
importredis.clients.jedis.Pipeline;
importredis.clients.jedis.Response;
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
Jedisredis=newJedis("127.0.0.1",6379,400000);
Map<String,String>data=newHashMap<String,String>();
redis.select(8);
redis.flushDB();
//hmset
longstart=System.currentTimeMillis();
//直接hmset
for(inti=0;i<10000;i++){
data.clear();
data.put("k_"+i,"v_"+i);
redis.hmset("key_"+i,data);
}
longend=System.currentTimeMillis();
System.out.println("dbsize:["+redis.dbSize()+"]..");
System.out.println("hmsetwithoutpipelineused["+(end-start)/1000+"]seconds..");
redis.select(8);
redis.flushDB();
//使用pipelinehmset
Pipelinep=redis.pipelined();
start=System.currentTimeMillis();
for(inti=0;i<10000;i++){
data.clear();
data.put("k_"+i,"v_"+i);
p.hmset("key_"+i,data);
}
p.sync();
end=System.currentTimeMillis();
System.out.println("dbsize:["+redis.dbSize()+"]..");
System.out.println("hmsetwithpipelineused["+(end-start)/1000+"]seconds..");
//hmget
Set<String>keys=redis.keys("*");
//直接使用Jedishgetall
start=System.currentTimeMillis();
Map<String,Map<String,String>>result=newHashMap<String,Map<String,String>>();
for(Stringkey:keys){
result.put(key,redis.hgetAll(key));
}
end=System.currentTimeMillis();
System.out.println("resultsize:["+result.size()+"]..");
System.out.println("hgetAllwithoutpipelineused["+(end-start)/1000+"]seconds..");
//使用pipelinehgetall
Map<String,Response<Map<String,String>>>responses=newHashMap<String,Response<Map<String,String>>>(keys.size());
result.clear();
start=System.currentTimeMillis();
for(Stringkey:keys){
responses.put(key,p.hgetAll(key));
}
p.sync();
for(Stringk:responses.keySet()){
result.put(k,responses.get(k).get());
}
end=System.currentTimeMillis();
System.out.println("resultsize:["+result.size()+"]..");
System.out.println("hgetAllwithpipelineused["+(end-start)/1000+"]seconds..");
redis.disconnect();
}
}
测试结果如下:
dbsize:[10000].. hmsetwithoutpipelineused[243]seconds.. dbsize:[10000].. hmsetwithpipelineused[0]seconds.. resultsize:[10000].. hgetAllwithoutpipelineused[243]seconds.. resultsize:[10000].. hgetAllwithpipelineused[0]seconds..
使用pipeline来批量读写10000条记录,就是小菜一碟,秒完。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。