當前位置:
首頁 > 知識 > Redis Pipeline原理分析

Redis Pipeline原理分析


1. 基本原理

1.1 為什麼會出現Pipeline

Redis本身是基於Request/Response協議的,正常情況下,客戶端發送一個命令,等待Redis應答,Redis在接收到命令,處理後應答。在這種情況下,如果同時需要執行大量的命令,那就是等待上一條命令應答後再執行,這中間不僅僅多了RTT(Round Time Trip),而且還頻繁的調用系統IO,發送網路請求。如下圖。

Redis Pipeline原理分析

為了提升效率,這時候Pipeline出現了,它允許客戶端可以一次發送多條命令,而不等待上一條命令執行的結果,這和網路的Nagel演算法有點像(TCP_NODELAY選項)。不僅減少了RTT,同時也減少了IO調用次數(IO調用涉及到用戶態到內核態之間的切換)。如下圖:

Redis Pipeline原理分析

客戶端這邊首先將執行的命令寫入到緩衝中,最後再一次性發送Redis。但是有一種情況就是,緩衝區的大小是有限制的,比如Jedis,限制為8192,超過了,則刷緩存,發送到Redis,但是不去處理Redis的應答,如上圖所示那樣。

1.2 實現原理

要支持Pipeline,其實既要服務端的支持,也要客戶端支持。對於服務端來說,所需要的是能夠處理一個客戶端通過同一個TCP連接發來的多個命令,可以理解為,這裡將多個命令切分,和處理單個命令一樣(之前老生常談的黏包現象),Redis就是這樣處理的。而客戶端,則是要將多個命令緩存起來,緩衝區滿了就發送,然後再寫緩衝,最後才處理Redis的應答,如Jedis。

1.3 從哪個方面提升性能

正如上面所說的,一個是RTT,節省往返時間,但是另一個原因也很重要,就是IO系統調用。一個read系統調用,需要從用戶態,切換到內核態。

1.4 注意點

Redis的Pipeline和Transaction不同,Transaction會存儲客戶端的命令,最後一次性執行,而Pipeline則是處理一條,響應一條,但是這裡卻有一點,就是客戶端會並不會調用read去讀取socket裡面的緩衝數據,這也就造就了,如果Redis應答的數據填滿了該接收緩衝(SO_RECVBUF),那麼客戶端會通過ACK,WIN=0(接收窗口)來控制服務端不能再發送數據,那樣子,數據就會緩衝在Redis的客戶端應答列表裡面。所以需要注意控制Pipeline的大小。如下圖:

Redis Pipeline原理分析


2. Codis Pipeline

在一般情況下,都會在Redis前面使用一個代理,來作負載以及高可用。這裡在公司裡面使用的是Codis,以Codis 3.2版本為例(3.2版本是支持Pipeline的)。

Codis在接收到客戶端請求後,首先根據Key來計算出一個hash,映射到對應slots,然後轉發請求到slots對應的Redis。在這過程中,一個客戶端的多個請求,有可能會對應多個Redis,這個時候就需要保證請求的有序性(不能亂序),Codis採用了一個Tasks隊列,將請求依次放入隊列,然後loopWriter從裡面取,如果Task請求沒有應答,則等待(這裡和Java的Future是類似的)。內部BackenRedis是通過channel來進行通信的,dispatcher將Request通過channel發送到BackenRedis,然後BackenRedis處理完該請求,則將值填充到該Request裡面。最後loopWriter等待到了值,則返回給客戶端。如下圖所示:

Redis Pipeline原理分析

3. 總結

  1. Pipeline減少了RTT,也減少了IO調用次數(IO調用涉及到用戶態到內核態之間的切換)
  2. 需要控制Pipeline的大小,否則會消耗Redis的內存
  3. Codis 3.2 Pipeline默認10K,3.1則是1024
    Jedis客戶端緩存是8192,超過該大小則刷新緩存,或者直接發送

4. 參考資料

  1. Redis官方文檔:https://redis.io/topics/pipelining
  2. Redis 協議
  3. Redis源碼(請求處理響應部分)
  4. Codis源碼

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

redis源碼筆記(一)——從redis的啟動到command的分發
MySQL實現自動使用uuid作為主鍵以及解決不能調用觸發器的一點思路

TAG:達人科技 |

您可能感興趣

Remote Procedure Call基本原理
BGP Confederation原理實踐
Leap Motion發布AR頭顯Project North Star原理圖
AlphaGo之父DeepMind再出神作,PrediNet原理詳解
Prometheus原理和源碼分析
Flutter Dart Framework原理簡解
Altium Desinger 設計一個簡單的原理圖
LruCache原理分析
CGLIB(Code Generation Library) 介紹與原理
ArrayList,LinkedList,Vector基本原理與實現
Spring Cloud斷路器Hystrix原理讀書筆記
集群管理工具KafkaAdminClient——原理與示例
C#ConcurrentBag的實現原理
Session和Cookies的基本原理
札記CAS、AQS、CountDownLatch、CyclicBarrier的原理
從Paxos到zookeeper分散式一致性原理與實踐-Zookeeper與Paxos
Photoshop工作原理
ajax,long poll,websocket連接的區別原理
微服務運維減負:Istio Service Mesh原理+實戰
springmvc原理詳解(手寫springmvc)