Redis性能調優之Pipeline(管道)

一、性能問題

1、概述

Redis使用的是客戶端-服務端這種CS模型和請求/響應的TCP服務器。這意味着通常情況下一個請求會遵循以下步驟:

  • 客戶端向服務端發送一個請求,並監聽SOCKET返回,通常是阻塞模式,等待服務端響應。
  • 服務端處理客戶端發來的命令並進行處理,最終將結果返回給客戶端。

redis確實是非阻塞,但是redis服務端處理是非阻塞,用戶端來講還是阻塞。
至於redis爲什麼這麼快,可以看這個一文帶你徹底掌握Redis爲什麼這麼快?

2、舉例

也就是說一個客戶端可以通過一個socket連接發起多個請求命令,每個請求命令發出後客戶端通常會阻塞並等待redis服務器處理,redis處理完請求命令後會將結果通過響應報文返回給客戶端。因爲當執行多條命令的時候都需要等待上條命令執行完畢才能執行,比如:

set k1 1
keys *
get k1

Redis採取IO由於通信會有網絡延遲,假如 client 和 server 之間的包傳輸時間需要0.125秒。那麼上面的三個命令6個報文至少需要0.75秒才能完成。這樣即使 redis 每秒能處理100個命令,而我們的 client 也只能一秒鐘發出四個命令。這顯然沒有充分利用 redis 的處理能力。

二、什麼是Pipeline

我們已經知道上面的問題了,也知道性能是耗費再了通信上,這時候pipeline橫空出世,他的目的是將一批命令打包到一個內部維護的queue裏,然後建立socket與server交互,這時候是隻會發送一次命令,也就是隻會交互一次,然後queue內的命令都執行完後會一起返回結果,這樣大大減少了通信的次數,自然降低了通信所耗費的時間。queue是先進先出,所以可以保證執行順序。

三、說明

並不是pipeline就無敵了,以後都用這個。這需要看需求的。比如你的需求get key 實時性很高,而且要用他的返回值做處理。那你把get key這個命令與其他100個命令放到一起去批處理進行,那反而在業務角度分析,效率更爲低下。

四、測試

如下demo是從https://blog.csdn.net/u011489043/article/details/78769428這個地址而來,如有侵權請聯繫我~

/*
 * 測試普通模式與 PipeLine 模式的效率: 
 * 測試方法:向 redis 中插入 10000 組數據
 */
public static void testPipeLineAndNormal(Jedis jedis) throws InterruptedException {
	Logger logger = Logger.getLogger("javasoft");
	long start = System.currentTimeMillis();
	for (int i = 0; i < 10000; i++) {
		jedis.set(String.valueOf(i), String.valueOf(i));
	}
	long end = System.currentTimeMillis();
	logger.info("the jedis total time is:" + (end - start));

	Pipeline pipe = jedis.pipelined(); // 先創建一個 pipeline 的鏈接對象
	long start_pipe = System.currentTimeMillis();
	for (int i = 0; i < 10000; i++) {
		pipe.set(String.valueOf(i), String.valueOf(i));
	}
	pipe.sync(); // 獲取所有的 response
	long end_pipe = System.currentTimeMillis();
	logger.info("the pipe total time is:" + (end_pipe - start_pipe));
	
	BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>();
	long begin = System.currentTimeMillis();
	for (int i = 0; i < 10000; i++) {
		logQueue.put("i=" + i);
	}
	long stop = System.currentTimeMillis();
	logger.info("the BlockingQueue total time is:" + (stop - begin));
}

在這裏插入圖片描述

五、使用場景

不適用場景:

  • 要求可靠性高,每次都需要實時知道這次操作是否成功,數據是否寫入redis了等對實時性的這種需求都不適合。

適用場景:

  • 對實時性要求不高的
  • 批量的將數據寫入 redis,允許一定比例的寫入失敗

比如羣發短信、郵件這種,失敗了我補償,我不需要及時知道發送結果的,這種用pipeline合適 。

六、總結

  • 什麼是Pipeline
  • Pipeline可以性能調優
  • 使用場景

七、個人公衆號

微信公衆號【Java碼農社區】
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章