jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
          http://blog.csdn.net/oyl822/article/details/44460949

          Redis是一個響應式的服務,當客戶端發(fā)送一個請求后,就處于阻塞狀態(tài)等待Redis返回結果。這樣一次命令消耗的時間就包括三個部分:請求從客戶端到服務器的時間、結果從服務器到客戶端的時間和命令真正執(zhí)行時間,前兩個部分消耗的時間總和稱為RTT(Round Trip Time),當客戶端與服務器存在網絡延時時,RTT就可能會很大,這樣就會導致性能問題。管道(Pipeline)就是為了改善這個情況的,利用管道,客戶端可以一次性發(fā)送多個請求而不用等待服務器的響應,待所有命令都發(fā)送完后再一次性讀取服務的響應,這樣可以極大的降低RTT時間從而提升性能。


          下面這個例子,在本地分別以普通請求和管道對一個鍵調用2000次incr命令的測試

          [java] view plain copy
          1. public class App   
          2. {  
          3.     public static void main( String[] args ) {  
          4.         long start = System.currentTimeMillis();  
          5.         withoutPipeline();  
          6.         System.out.println("Without Pipeline takes: " + (System.currentTimeMillis() - start) + " ms.");  
          7.           
          8.         start = System.currentTimeMillis();  
          9.         withPipeline();  
          10.         System.out.println("With Pipeline takes: " + (System.currentTimeMillis() - start) + " ms.");  
          11.     }  
          12.       
          13.     public static void withPipeline() {  
          14.         Jedis jedis = null;  
          15.           
          16.         try {  
          17.             jedis = new Jedis("localhost", 6379);  
          18.             jedis.flushDB();  
          19.             Pipeline p = jedis.pipelined();  
          20.               
          21.             p.set("thekey", Integer.toString(0));  
          22.               
          23.             for (int i = 1; i <= 2000; i++) {  
          24.                 p.incr("thekey");  
          25.             }  
          26.               
          27.             Response<String> r = p.get("thekey");  
          28.               
          29.             p.sync();  
          30.               
          31.             System.out.println(r.get());  
          32.         } finally {  
          33.             jedis.close();  
          34.         }  
          35.           
          36.     }  
          37.       
          38.     public static void withoutPipeline() {  
          39.         Jedis jedis = null;  
          40.           
          41.         try {  
          42.             jedis = new Jedis("localhost", 6379);  
          43.             jedis.flushDB();  
          44.             jedis.set("thekey", Integer.toString(0));  
          45.               
          46.             for (int i = 1; i <= 2000; i++) {  
          47.                 jedis.incr("thekey");  
          48.             }  
          49.               
          50.             System.out.println(jedis.get("thekey"));  
          51.         } finally {  
          52.             jedis.close();  
          53.         }  
          54.           
          55.     }  
          56. }  
          57.   
          58. //輸出結果  
          59. 2000  
          60. Without Pipeline takes: 183 ms.  
          61. 2000  
          62. With Pipeline takes: 47 ms.  

          結果很直觀的反映出兩者的差別,要知道這是在本地測試,幾乎不存在網絡延時的問題,如果是在不同的網段測試的話,效果會更明顯。雖然管道在一定程度上對性能有所提升,但是在使用時一點要注意,每個命令的返回結果是先被緩存在服務器端的,最后一次性返回給客戶端。如果一次批量提交涉及大量的返回結果,可能會導至服務器的內存溢出,這在生產環(huán)境是致命的,一次批次處理多少量,最好在設計階段做出合理評估。


          最后,管道只是一個方案,并不意味著在任何時候都要盡可能的使用它,而是應該結合考慮網絡延遲時間、業(yè)務涉及的請求量等等因素綜合考慮,畢竟創(chuàng)建管道本身也會有一定的消耗。

          posted on 2016-12-20 15:25 jinfeng_wang 閱讀(145) 評論(0)  編輯  收藏 所屬分類: 2016-REDIS
          主站蜘蛛池模板: 建平县| 昌吉市| 临城县| 鄂托克前旗| 张家港市| 迁安市| 阿拉尔市| 伽师县| 凤冈县| 南江县| 福泉市| 惠州市| 西青区| 璧山县| 和林格尔县| 交城县| 个旧市| 长子县| 沐川县| 轮台县| 高邑县| 绥中县| 蓬安县| 静乐县| 休宁县| 彭水| 东乌珠穆沁旗| 宣汉县| 合作市| 甘孜| 康乐县| 台南县| 囊谦县| 蒲城县| 上思县| 耒阳市| 白城市| 班玛县| 登封市| 商都县| 临洮县|