1. 程式人生 > >【Redis】Redis的Pipeline管道,批量操作,節省大量網路往返時間

【Redis】Redis的Pipeline管道,批量操作,節省大量網路往返時間

一般情況下,大家使用redis去put/get都是先拿到一個jedis例項,然後操作,然後釋放連線;這種模式是  

請求-響應,請求-響應

這種模式,下一次請求必須得等第一次請求響應回來之後才可以,因為redis是單執行緒的,按部就班,一步一步來。

而pipeline管道改變了這種請求模式,客戶端可以一次傳送多個命令,無須等待伺服器的返回,

請求,請求,請求,響應,響應,響應

這種模式

這就大大減少了影響效能的關鍵因素-網路往返時間

下面就上面兩種模式以及JDK的map三者做一個性能比較

package redis;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;

/**
 * @Type ShardRedisDemo.java
 * @Desc
 * @author chiwei
 * @date 2016年6月13日 下午3:24:25
 * @version
 */
public class ShardRedisDemo {

    public static void main(String[] args) throws InterruptedException {
        ShardRedisClient src = new ShardRedisClient();
        src.setServers("redis://172.23.26.135:7379");
        src.init();
        int count = 10000;
        ShardedJedis sj = src.getResource();
        long begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            sj.set("a" + i, "v" + i);
        }
        sj.close();
        System.out.println(System.currentTimeMillis() - begin);
        sj = src.getResource();
        ShardedJedisPipeline p = sj.pipelined();
        begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            p.set("ap" + i, "vp" + i);
        }
        p.sync();
        sj.close();
        System.out.println(System.currentTimeMillis() - begin);
        BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>();
        begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            logQueue.put("i=" + i);
        }
        System.out.println(System.currentTimeMillis() - begin);
    }

}

/**
 * Revision history
 * -------------------------------------------------------------------------
 * 
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2016年6月13日 chiwei create
 */
結果如下:
45027
116
11
大家看相對時間就行了,我測試時是經過VPN連的redis,由此結果可見pipeline的效能驚人的高。

但是pipeline適合於什麼樣的場景使用呢?



有些系統可能對可靠性要求很高,每次操作都需要立馬知道這次操作是否成功,是否資料已經寫進redis了,那這種場景就不適合。

還有的系統,可能是批量的將資料寫入redis,允許一定比例的寫入失敗,那麼這種場景就可以使用了,比如10000條一下進入redis,可能失敗了2條無所謂,後期有補償機制就行了,比如簡訊群發這種場景,如果一下群發10000條,按照第一種模式去實現,那這個請求過來,要很久才能給客戶端響應,這個延遲就太長了,如果客戶端請求設定了超時時間5秒,那肯定就丟擲異常了,而且本身群發簡訊要求實時性也沒那麼高,這時候用pipeline最好了。