1. 程式人生 > >單程序單執行緒的Redis如何能夠高併發

單程序單執行緒的Redis如何能夠高併發

1、基本原理 
採用多路 I/O 複用技術可以讓單個執行緒高效的處理多個連線請求(儘量減少網路IO的時間消耗) 
(1)為什麼不採用多程序或多執行緒處理?

多執行緒處理可能涉及到鎖 
多執行緒處理會涉及到執行緒切換而消耗CPU

(2)單執行緒處理的缺點?

無法發揮多核CPU效能,不過可以通過在單機開多個Redis例項來完善

2、Redis不存線上程安全問題? 
Redis採用了執行緒封閉的方式,把任務封閉在一個執行緒,自然避免了執行緒安全問題,不過對於需要依賴多個redis操作的複合操作來說,依然需要鎖,而且有可能是分散式鎖

3、什麼是多路I/O複用(Epoll) 
(1) 網路IO都是通過Socket實現,Server在某一個埠持續監聽,客戶端通過Socket(IP+Port)與伺服器建立連線(ServerSocket.accept),成功建立連線之後,就可以使用Socket中封裝的InputStream和OutputStream進行IO互動了。針對每個客戶端,Server都會建立一個新執行緒專門用於處理 
(2) 預設情況下,網路IO是阻塞模式,即伺服器執行緒在資料到來之前處於【阻塞】狀態,等到資料到達,會自動喚醒伺服器執行緒,著手進行處理。阻塞模式下,一個執行緒只能處理一個流的IO事件 
(3) 為了提升伺服器執行緒處理效率,有以下三種思路

(1)非阻塞【忙輪詢】:採用死迴圈方式輪詢每一個流,如果有IO事件就處理,這樣可以使得一個執行緒可以處理多個流,但是效率不高,容易導致CPU空轉

(2)Select代理(無差別輪詢):可以觀察多個流的IO事件,如果所有流都沒有IO事件,則將執行緒進入阻塞狀態,如果有一個或多個發生了IO事件,則喚醒執行緒去處理。但是還是得遍歷所有的流,才能找出哪些流需要處理。如果流個數為N,則時間複雜度為O(N)

(3)Epoll代理:Select代理有一個缺點,執行緒在被喚醒後輪詢所有的Stream,還是存在無效操作。 Epoll會哪個流發生了怎樣的I/O事件通知處理執行緒,因此對這些流的操作都是有意義的,複雜度降低到了O(1)

4、其它開源軟體採用的模型

Nginx:多程序單執行緒模型 
Memcached:單程序多執行緒模型