Java使用Pipeline對Redis批量讀寫(hmset&hgetall)

通常狀況下,Redis Client端發出一個請求後,一般會阻塞並等待Redis服務端處理,Redis服務端處理完後請求命令後會將結果經過響應報文返回給Client。
這有點相似於HBase的Scan,一般是Client端獲取每一條記錄都是一次RPC調用服務端。
在Redis中,有沒有相似HBase Scanner Caching的東西呢,一次請求,返回多條記錄呢?
有,這就是Pipline。官方介紹 http://redis.io/topics/pipelining java

經過pipeline方式當有大批量的操做時候,咱們能夠節省不少原來浪費在網絡延遲的時間,須要注意到是用pipeline方式打包命令發送,redis必須在處理完全部命令前先緩存起全部命令的處理結果。打包的命令越多,緩存消耗內存也越多。因此並非打包的命令越多越好。 redis

使用Pipeline在對Redis批量讀寫的時候,性能上有很是大的提高。 緩存

使用Java測試了一下: 網絡

 
  1. package com.lxw1234.redis;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import java.util.Set;
  6.  
  7. import redis.clients.jedis.Jedis;
  8. import redis.clients.jedis.Pipeline;
  9. import redis.clients.jedis.Response;
  10.  
  11.  
  12. public class Test {
  13. public static void main(String[] args) throws Exception {
  14. Jedis redis = new Jedis("127.0.0.1", 6379, 400000);
  15. Map<String,String> data = new HashMap<String,String>();
  16. redis.select(8);
  17. redis.flushDB();
  18. //hmset
  19. long start = System.currentTimeMillis();
  20. //直接hmset
  21. for (int i=0;i<10000;i++) {
  22. data.clear();
  23. data.put("k_" + i, "v_" + i);
  24. redis.hmset("key_" + i, data);
  25. }
  26. long end = System.currentTimeMillis();
  27. System.out.println("dbsize:[" + redis.dbSize() + "] .. ");
  28. System.out.println("hmset without pipeline used [" + (end - start) / 1000 + "] seconds ..");
  29. redis.select(8);
  30. redis.flushDB();
  31. //使用pipeline hmset
  32. Pipeline p = redis.pipelined();
  33. start = System.currentTimeMillis();
  34. for (int i=0;i<10000;i++) {
  35. data.clear();
  36. data.put("k_" + i, "v_" + i);
  37. p.hmset("key_" + i, data);
  38. }
  39. p.sync();
  40. end = System.currentTimeMillis();
  41. System.out.println("dbsize:[" + redis.dbSize() + "] .. ");
  42. System.out.println("hmset with pipeline used [" + (end - start) / 1000 + "] seconds ..");
  43. //hmget
  44. Set keys = redis.keys("*");
  45. //直接使用Jedis hgetall
  46. start = System.currentTimeMillis();
  47. Map<String,Map<String,String>> result = new HashMap<String,Map<String,String>>();
  48. for(String key : keys) {
  49. result.put(key, redis.hgetAll(key));
  50. }
  51. end = System.currentTimeMillis();
  52. System.out.println("result size:[" + result.size() + "] ..");
  53. System.out.println("hgetAll without pipeline used [" + (end - start) / 1000 + "] seconds ..");
  54. //使用pipeline hgetall
  55. Map<String,Response<Map<String,String>>> responses = new HashMap<String,Response<Map<String,String>>>(keys.size());
  56. result.clear();
  57. start = System.currentTimeMillis();
  58. for(String key : keys) {
  59. responses.put(key, p.hgetAll(key));
  60. }
  61. p.sync();
  62. for(String k : responses.keySet()) {
  63. result.put(k, responses.get(k).get());
  64. }
  65. end = System.currentTimeMillis();
  66. System.out.println("result size:[" + result.size() + "] ..");
  67. System.out.println("hgetAll with pipeline used [" + (end - start) / 1000 + "] seconds ..");
  68. redis.disconnect();
  69. }
  70. }
  71.  

測試結果以下: 性能

 
  1. dbsize:[10000] ..
  2. hmset without pipeline used [243] seconds ..
  3. dbsize:[10000] ..
  4. hmset with pipeline used [0] seconds ..
  5. result size:[10000] ..
  6. hgetAll without pipeline used [243] seconds ..
  7. result size:[10000] ..
  8. hgetAll with pipeline used [0] seconds ..

使用pipeline來批量讀寫10000條記錄,就是小菜一碟,秒完。 測試

相關文章
相關標籤/搜索