眾所周知Redis是單進程單線程的應用,在如今多核橫行的時代,我們不免有疑問,單線程的redis怎么就成了高性能的代表
當有多個線程同時調用redis的時候,那么單線程的redis是怎么處理的呢,這里就不得不說redis內部的IO模型
首先要提到幾個概念,阻塞IO,非阻塞IO,同步IO,異步IO,多路復用
首先我們要理解IO的過程才能更好的理解上面這幾種情況,IO分為兩步,第一階段是數據准備,第二階段是數據復制階段,所謂數據復制階段就是講數據從內核復制到用戶空間
所謂阻塞IO,即我們傳統的阻塞概念,當一個客戶端請求發起之后線程會掛起,等待服務端返回請求結果然后繼續處理業務邏輯
非阻塞IO,有人認為非阻塞==異步,其實這個是不准確的,非阻塞IO的非阻塞其實只要體現在IO的第一階段,非阻塞IO會定時check服務端的數據准備情況,這個階段是非阻塞的,但是一旦數據准備階段完成了,線程就會阻塞的進行IO的第二階段,即數據復制,所以非阻塞IO還是屬於同步IO
所以只要有線程阻塞的情況都是屬於同步IO,線程完全不會阻塞掛起的才是真正的異步IO
多路復用API,多路復用最常用的就是select和epoll,多路復用的最大的特點就是多路,一個select可以同時處理多個套接字的讀寫請求,這時候IO的阻塞點往往是多路復用的API,而不是IO操作本身
在redis中的IO模型就是使用多路復用API進程客戶端的檢測,多路復用API可以同時監聽多個客戶端的讀寫操作,多路復用API會檢測客戶端的請求是讀操作還是寫操作,往往API會有一個timeout,在這個時間內redis線程會阻塞,進行套接字的監聽,redis會給每個客戶端套接字匹配一個指令隊列,按照隊列進行處理,同時也會將操作結果放到輸出隊列
正是通過這種多路復用的思想進行非阻塞的IO,這樣才保證了redis的高效