jinfeng_wang

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

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

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

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


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

          posted on 2016-12-20 15:25 jinfeng_wang 閱讀(145) 評論(0)  編輯  收藏 所屬分類: 2016-REDIS
          主站蜘蛛池模板: 枞阳县| 平江县| 吉木萨尔县| 怀仁县| 道孚县| 扎赉特旗| 唐山市| 齐齐哈尔市| 神池县| 黑山县| 资讯 | 陆川县| 华坪县| 鲁甸县| 大方县| 新田县| 安远县| 罗城| 益阳市| 平定县| 高要市| 新竹县| 怀远县| 琼结县| 进贤县| 自贡市| 托里县| 凌海市| 建湖县| 北碚区| 从江县| 富民县| 大竹县| 会理县| 栾城县| 阿合奇县| 桓仁| 富蕴县| 松潘县| 重庆市| 安远县|