1. 程式人生 > >Redis的效能瓶頸

Redis的效能瓶頸

1.首先Redis為什麼這麼快?

1.基於記憶體,不會受到硬碟IO速度的限制

2.單執行緒,避免了多執行緒切換導致的CPU消耗,也不用考慮鎖的問題,不存在加鎖釋放鎖的操作,也不存在因死鎖而導致的效能消耗

3.使用多路I/O複用模型,非阻塞IO

 多路I/O複用模型是利用 select、poll、epoll 可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前執行緒阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,於是程式就會輪詢一遍所有的流(epoll 是隻輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。

這裡的多路指的是多個請求,複用指的是複用同一個執行緒,採用多路 I/O 複用技術可以讓單個執行緒高效的處理多個連線請求(儘量減少網路 IO 的時間消耗),且 Redis 在記憶體中操作資料的速度非常快,也就是說記憶體內的操作不會成為影響Redis效能的瓶頸,主要由以上幾點造就了 Redis 具有很高的吞吐量

2.Redis為什麼是單執行緒?

因為Redis是基於記憶體的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器記憶體的大小或者網路頻寬。既然單執行緒容易實現,而且CPU不會成為瓶頸,那就順理成章地採用單執行緒的方案了(畢竟採用多執行緒會有很多麻煩)。

也就是說,因為單執行緒實現及維護的成本低,加上單執行緒的效能已經非常高,所以就沒用多執行緒。

注意這裡的單執行緒,只是在處理我們的網路請求時只有一個執行緒來處理,Redis Server在執行時肯定不止一個執行緒,比如在持久化時會以子執行緒的方式執行

Redis的瓶頸:

1.機器記憶體大小,因為redis的資料放在記憶體裡,所以存放資料量的多少取決於記憶體的多少

2.網路頻寬

Redis客戶端執行一條命令分為如下四個過程:

1)傳送命令

2)命令排隊

3)命令執行

4)返回結果

其中1)+4)稱為Round Trip Time(RTT,往返時間)。

Redis的客戶端和服務端可能部署在不同的機器上。例如客戶端在北京,Redis服務端在上海,兩地直線距離約為1300公里,那麼1次RTT時間=1300×2/(300000×2/3)=13毫秒(光在真空中傳輸速度為每秒30萬公里,這裡假設光纖為光速的2/3),那麼客戶端在1秒內大約只能執行80次左右的命令,這個和Redis的高併發高吞吐特性背道而馳

所以要麼就在全國各地都有自己的Redis伺服器,然後就近訪問,要麼就使用Pipeline

Pipeline(流水線)機制能改善上面這類問題,它能將一組Redis命令進行組裝,通過一次RTT傳輸給Redis,再將這組Redis命令的執行結果按順序192返回給客戶端,下圖為沒有使用Pipeline執行了n條命令,整個過程需要n次RTT

沒有Pipeline執行n次命令模型

Pipeline並不是什麼新的技術或機制,很多技術上都使用過。而且RTT在不同網路環境下會有不同,例如同機房和同機器會比較快,跨機房跨地區會比較慢。Redis命令真正執行的時間通常在微秒級別,所以才會有Redis效能瓶頸是網路這樣的說法。

但大部分開發人員更傾向於使用高階語言客戶端中的Pipeline,目前大部分Redis客戶端都支援Pipeline