深入淺出Redis(三)高級特性:管道

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


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

public class App 
{
	public static void main( String[] args ) {
		long start = System.currentTimeMillis();
		withoutPipeline();
		System.out.println("Without Pipeline takes: " + (System.currentTimeMillis() - start) + " ms.");
		
		start = System.currentTimeMillis();
		withPipeline();
		System.out.println("With Pipeline takes: " + (System.currentTimeMillis() - start) + " ms.");
	}
	
    public static void withPipeline() {
    	Jedis jedis = null;
    	
    	try {
    		jedis = new Jedis("localhost", 6379);
    		jedis.flushDB();
    		Pipeline p = jedis.pipelined();
        	
        	p.set("thekey", Integer.toString(0));
        	
        	for (int i = 1; i <= 2000; i++) {
        		p.incr("thekey");
        	}
        	
        	Response<String> r = p.get("thekey");
        	
        	p.sync();
        	
        	System.out.println(r.get());
    	} finally {
    		jedis.close();
    	}
    	
    }
    
    public static void withoutPipeline() {
    	Jedis jedis = null;
    	
    	try {
    		jedis = new Jedis("localhost", 6379);
    		jedis.flushDB();
    		jedis.set("thekey", Integer.toString(0));
        	
        	for (int i = 1; i <= 2000; i++) {
        		jedis.incr("thekey");
        	}
        	
        	System.out.println(jedis.get("thekey"));
    	} finally {
    		jedis.close();
    	}
    	
    }
}

//輸出結果
2000
Without Pipeline takes: 183 ms.
2000
With Pipeline takes: 47 ms.

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


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章