Pipeline概念
Redis客戶端執(zhí)行一條命令分為如下四個(gè)過程:
- 發(fā)送命令
- 命令排隊(duì)
- 命令執(zhí)行
- 返回結(jié)果
其中际邻,1到4稱為Round Trip Time(RTT夏漱,往返時(shí)間)。
Redis提供了批量操作命令(例如mset朴乖、mget等)育灸,有效地節(jié)省了RTT驰后。但大部分命令是不支持批量操作的,例如要執(zhí)行n次hgetall命令懊烤,并沒有mhgetall命令存在梯醒,需要消耗n次RTT。Redis的客戶端和服務(wù)端可能部署在不同的機(jī)器上腌紧。例如客戶端在北京茸习,Redis服務(wù)器在上海,兩地直線距離1300公里壁肋,那么一次RTT時(shí)間= 1300 x2 / 3000000 x
2/3) = 13毫秒(光在真空中的傳輸速度為30萬(wàn)公里/秒号胚,這里假設(shè)光纖為光速的2/3),那么客戶端在1秒內(nèi)大約只能執(zhí)行80次左右的命令浸遗,這個(gè)Redis的高并發(fā)高吞吐特性背道而馳猫胁。
Pipeline(流水線)機(jī)制能改善上面這類問題,它能將一組Redis命令進(jìn)行組裝跛锌,通過一次RTT傳輸給Redis杜漠,再將這組Redis命令的執(zhí)行結(jié)果按順序返回給客戶端媒峡。
Jedis Pipeline使用
maven依賴:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Pipeline 操作如下:
JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");
try (Jedis jedis = pool.getResource()) {
//1.生成Pipeline
Pipeline p = jedis.pipelined();
p.set("fool", "bar");
p.zadd("foo", 1, "barowitch");
p.zadd("foo", 0, "barinsky");
p.zadd("foo", 0, "barikoviev");
Response<String> pipeString = p.get("fool");
Response<Set<String>> sose = p.zrange("foo", 0, -1);
// 2. 執(zhí)行
p.sync();
int soseSize = sose.get().size();
Set<String> setBack = sose.get();
}
pool.destroy();
原生批量命令與Pipeline對(duì)吧
可以使用Pipeline模擬出批量操作的效果抵卫,但是在使用時(shí)要注意它與原生批量命令的區(qū)別根资,主要包括如下幾點(diǎn):
- 原生批量命令是原子的,Pipeline是非原子的
- 原生批量命令是一個(gè)命令對(duì)應(yīng)多個(gè)key氢卡,Pipeline支持多個(gè)命令
- 原生批量命令是Redis服務(wù)端支持實(shí)現(xiàn)的,而Pipeline需要服務(wù)端和客戶端的共同配合