详解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条记录,就是小菜一碟,秒完。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。