久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis中管道機制的示例分析

199次閱讀
沒有評論

共計 3285 個字符,預計需要花費 9 分鐘才能閱讀完成。

這篇文章將為大家詳細講解有關 Redis 中管道機制的示例分析,丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Pipeline 簡介

Redis 客戶端執行一條命令:

發送命令

命令排隊

執行命令

返回結果

其中發送命令和返回結果可以稱為 Round Trip Time (RTT, 往返時間)。在 Redis 中提供了批量操作命令,例如 mget、mset 等,有效地節約了 RTT。但是大部分命令是不支持批量操作的。

為此 Redis 提供了一個稱為管道 (Pipeline) 的機制將一組 Redis 命令進行組裝,通過一次 RTT 傳輸給 Redis, 再將這些 Redis 命令的執行結果按順序傳遞給客戶端。即使用 pipeline 執行了 n 次命令,整個過程就只需要一次 RTT。

對 Pipeline 進行性能測試

我們使用 redis-benchmark 對 Pipeline 進行性能測試,該工具提供了 -P 的選項,此選項表示使用管道機制處理 n 條 Redis 請求,默認值為 1。測試如下:

#  不使用管道執行 get set 100000 次請求
[root@iz2zeaf3cg1099kiidi06mz ~]# redis-benchmark -t get,set -q -n 100000
SET: 55710.31 requests per second
GET: 54914.88 requests per second
#  每次 pipeline 組織的命令個數   為  100
[root@iz2zeaf3cg1099kiidi06mz ~]# redis-benchmark -P 100 -t get,set -q -n 100000
SET: 1020408.19 requests per second
GET: 1176470.62 requests per second
#  每次 pipeline 組織的命令個數   為  10000
[root@iz2zeaf3cg1099kiidi06mz ~]# redis-benchmark -P 10000 -t get,set -q -n 100000
SET: 321543.41 requests per second
GET: 241545.89 requests per second

從上面測試可以看出,使用 pipeline 的情況下 Redis 每秒處理的請求數遠大于 不使用 pipeline 的情況。

當然每次 pipeline 組織的命令個數不能沒有節制,否則一次組裝 Pipeline 數據量過大,一方面會增加 客戶端等待時間,另一方面會造成一定的網絡阻塞。

從上面的測試中也可以看出,如果一次 pipeline 組織的命令個數為 10000,但是它對應的 QPS 卻小于 一次 pipeline 命令個數為 100 的。所以每次組織 Pipeline 的命令個數不是越多越好,可以將一次包含大量命令的 Pipeline 拆分為 多個較小的 Pipeline 來完成。

Pipeline 關于 RTT 的說明

在官網上有一段這樣的描述:

大致意思就是:

Pipeline 管道機制不單單是為了減少 RTT 的一種方式,它實際上大大提高了 Redis 的 QPS。原因是,在沒有使用管道機制的情況下,從訪問數據結構和產生回復的角度來看,為每個命令提供服務是非常便宜的。但是從底層套接字的角度來看,這是非常昂貴的,這涉及 read()和 write()系統調用,從用戶態切換到內核態,這種上下文切換開銷是巨大。而使用 Pipeline 的情況下,通常使用單個 read()系統調用讀取許多命令,然后使用單個 write()系統調用傳遞多個回復, 這樣就提高了 QPS

批量命令與 Pipeline 對比

批量命令是原子的,Pipeline 是非原子的

批量命令是一個命令多個 key,Pipeline 支持多個命令

批量命令是 Redis 服務端實現的,而 Pipeline 需要服務端和客戶端共同實現

使用 jedis 執行 pipeline

public class JedisUtils { private static final JedisUtils jedisutils = new JedisUtils();
 public static JedisUtils getInstance() {
 return jedisutils;
 }
 public JedisPool getPool(String ip, Integer port) { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
 jedisPoolConfig.setMaxIdle(RedisConfig.MAX_IDLE);
 jedisPoolConfig.setMaxTotal(RedisConfig.MAX_ACTIVE);
 jedisPoolConfig.setMaxWaitMillis(RedisConfig.MAX_WAIT);
 jedisPoolConfig.setTestOnBorrow(true);
 jedisPoolConfig.setTestOnReturn(true);
 JedisPool pool = new JedisPool(jedisPoolConfig, ip, port,RedisConfig.TIMEOUT,RedisConfig.PASSWORD);
 return pool;
 }
 public Jedis getJedis(String ip, Integer port) {
 Jedis jedis = null;
 int count = 0;
 while (jedis == null   count   RedisConfig.RETRY_NUM) {
 try { jedis = getInstance().getPool(ip, port).getResource();
 } catch (Exception e) {
 System.out.println( get redis failed 
 }
 count++;
 }
 return jedis;
 }
 public void closeJedis(Jedis jedis) { if (jedis != null) { jedis.close();
 }
 }
 public static void main(String[] args) throws InterruptedException { Jedis jedis = JedisUtils.getInstance().getJedis(127.0.0.1 , 6379);
 Pipeline pipeline = jedis.pipelined();
 pipeline.set( hello ,  world 
 pipeline.incr( counter 
 System.out.println( 還沒執行命令 
 Thread.sleep(100000);
 System.out.println( 這里才開始執行 
 pipeline.sync();
 }
}

在睡眠 100s 的時候查看 Redis,可以看到此時在 pipeline 中的命令并沒有執行,命令都被放在一個隊列中等待執行:

127.0.0.1:6379  get hello
(nil)
127.0.0.1:6379  get counter
(nil)

睡眠結束后,使用 pipeline.sync() 完成此次 pipeline 對象的調用。

127.0.0.1:6379  get hello
 world 
127.0.0.1:6379  get counter
 1

必須要執行 pipeline.sync() 才能最終執行命令,當然可以使用 pipeline.syncANdReturnAll 回調機制將 pipeline 響應命令進行返回。

關于“Redis 中管道機制的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-04發表,共計3285字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 金阳县| 扎赉特旗| 白朗县| 海林市| 凤台县| 湟源县| 贡觉县| 堆龙德庆县| 东阿县| 彭水| 舟曲县| 左贡县| 内江市| 滨州市| 旅游| 五莲县| 枣强县| 黄梅县| 彩票| 柳河县| 赫章县| 石嘴山市| 含山县| 万山特区| 河西区| 嵊泗县| 青阳县| 如皋市| 江西省| 清流县| 临江市| 宝应县| 鸡东县| 壶关县| 怀来县| 嘉义县| 兴安县| 邹城市| 平陆县| 临武县| 汝阳县|