Redis Pipeline 批處理任務
今天分享一個Redis的小功能,Pipeline(流水線)。Pipeline能夠將一組Redis命令組裝起來,通過一次請求發給Redis服務端,Redis服務端執行完這些命令之後再將這些命令的結果一次性返回給客戶端。
Redis執行一條命令分為四個步驟:
- 傳送命令
- 命令排隊
- 命令執行
- 返回結果
其中傳送命令和返回結果兩步的時間和稱之為Rount Trip Time(RTT,往返時間)。假設我們以工要向Redis服務端傳送 n 條訊息,使用Pipeline就能幫我們節省 n - 1 次RTT時間。
如果Redis客戶端在上海,服務端在北京,兩地直線距離1300公里,假設光纖為光速的 2/3,那麼一次RTT的時間為 1300 * 2 / (300000 * 2 / 3) = 13 毫秒,而Redis處理命令的時間通常在微妙級別,所以有Redis的效能瓶頸在網路這麼一種說法。
所以在網路延遲比較大的場景下使用Pipeline來處理多條訊息,可以大幅度減少請求響應總時間。
Redis的Pipeline功能需要客戶端的支援,下面有一段Jedis客戶端使用Pipeline功能的程式碼:
public static void testPipeline(){
//生成pipeline物件
Pipeline pipelined = jedis.pipelined();
//向pipeline物件中新增命令
pipelined.set("hello", "world");
pipelined.incr("incrnum");
pipelined.get ("hello");
//呼叫syncAndReturnAll方法會執行pipeline中的命令,並且返回結果
//pipelined.sync()會執行pipeline中的命令,不返回結果
List<Object> list = pipelined.syncAndReturnAll();
System.out.println(list);
}
Redis原生也提供了一些批處理命令,如mget、mset等,也能減少多條命令的RTT時間,但是這些原生的批處理命令只能提供單一的命令,不像Pipeline命令那樣可以處理很多不同型別的命令。
Pipeline命令雖然好用,但使用的時候還是要注意一些問題的:
- Pipeline是非原子的
- 如果一次組裝的Pipeline資料量過大,會增加客戶端的等待時間,也會造成Redis服務端的阻塞,可以考慮將一次資料量過大的Pipeline命令拆分成多個小的Pipeline命令來完成。
小功能大用處,一天一個小知識點,學到就是賺到。
喜歡這篇文章的朋友,歡迎掃描下圖關注公眾號lebronchen,第一時間收到更新內容。