redis學習筆記之pipeline

redis是一個cs模式的tcp server,使用和http相似的請求響應協議。一個client能夠經過一個socket鏈接發起多個請求命令。每一個請求命令發出後client一般 會阻塞並等待redis服務處理,redis處理完後請求命令後會將結果經過響應報文返回給client。基本的通訊過程以下
Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4
基 本上四個命令須要8個tcp報文才能完成。因爲通訊會有網絡延遲,假如從client和server之間的包傳輸時間須要0.125秒。那麼上面的四個命 令8個報文至少會須要1秒才能完成。這樣即便redis每秒能處理100個命令,而咱們的client也只能一秒鐘發出四個命令。這顯示沒有充分利用 redis的處理能力。除了能夠利用mget,mset 之類的單條命令處理多個key的命令外
咱們還能夠利用pipeline的方式從client打包多條命令一塊兒發出,不須要等待單條命令的響應返回,而redis服務端會處理完多條命令後會將多條命令的處理結果打包到一塊兒返回給客戶端。通訊過程以下

Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4

假 設不會由於tcp 報文過長而被拆分。可能兩個tcp報文就能完成四條命令,client能夠將四個incr命令放到一個tcp報文一塊兒發送,server則能夠將四條命令 的處理結果放到一個tcp報文返回。經過pipeline方式當有大批量的操做時候。咱們能夠節省不少原來浪費在網絡延遲的時間。須要注意到是用 pipeline方式打包命令發送,redis必須在處理完全部命令前先緩存起全部命令的處理結果。打包的命令越多,緩存消耗內存也越多。因此並是否是打 包的命令越多越好。具體多少合適須要根據具體狀況測試。下面是個jredis客戶端使用pipeline的測試
package jredisStudy;
import org.jredis.JRedis;
import org.jredis.connector.ConnectionSpec;
import org.jredis.ri.alphazero.JRedisClient;
import org.jredis.ri.alphazero.JRedisPipelineService;
import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;
public class PipeLineTest {
    public static void main(String[] args) {
          long start =System.currentTimeMillis();
          usePipeline();
          long end =System.currentTimeMillis();
          System.out.println(end-start);

          start = System.currentTimeMillis();
          withoutPipeline();
          end  =System.currentTimeMillis();
          System.out.println(end-start);
  
    }
    
    private static void withoutPipeline()
    {
         try { 
             JRedis jredis = new JRedisClient("192.168.56.55",6379);
               for(int i =0 ; i < 100000 ; i++)
                {
                   jredis.incr("test2");
                }
               jredis.quit();
        } catch (Exception e) {
        }
    }

    private static void usePipeline() {
        try {
            ConnectionSpec spec =DefaultConnectionSpec.newSpec("192.168.56.55", 6379, 0, null);
            JRedis jredis = newJRedisPipelineService(spec);
            for(int i =0 ; i <100000 ; i++)
            {
               jredis.incr("test2");
            }
            jredis.quit();
        } catch (Exception e) {
        }
    }
}
輸出
103408 //使用了pipeline
104598 //沒有使用

測試結果不是很明顯,這應該是跟個人測試環境有關。我是在本身win鏈接虛擬機的linux。網絡延遲比較小。因此pipeline
優點不明顯。若是網絡延遲小的話,最好仍是不用pipeline。除了增長複雜外,帶來的性能提高不明顯。java

更多精彩內容請關注:http://bbs.superwu.cn linux

關注超人學院微信二維碼 redis

關注超人學院java免費學習交流羣: 緩存

相關文章
相關標籤/搜索