不做過多展開,本篇主要記錄我對Redis如何保證原子性問題的思考,以及此問題衍生出的問題,如有錯誤和疑問歡迎大家在底部留言。
答案很簡單,因為redis是單線程。
問題來了,既然Redis是單線程,可以保證原子性,那麽它的異步和非阻塞是什麽?單線程如何實現異步和非阻塞?
再查閱了很多資料之後,我發現我對於 同步/異步 、 阻塞/非阻塞 以及 單線程/多線程 的概念有些不清晰,下面給出簡單解釋。
同步/異步 :首先同步和異步主要是從消息通知機制來講起的。
同步:壹個任務的完成必須依賴另壹個任務,兩個要麽都成功要麽都失敗,是壹種可靠的任務序列。當壹個同步調用發生後,調用者必須等待返回結果,才能繼續後面任務的執行。
異步:不需要等待被依賴任務的完成,只需要完成自己的任務就可以,所以是不可靠任務序列。當壹個異步調用發生後,調用者不必等待返回結果,調用者可以去做其他的事情,被調用部件在處理完成後,通過(狀態、通知、回調)來通知調用者。
阻塞/非阻塞 :阻塞和非阻塞和調用者等待消息通知時的狀態有關。很重要,不要和同步混淆。
阻塞:調用者在等待通知的過程中,不能執行其他業務,傻傻的等待通知到來。
非阻塞:和阻塞相反,調用者可以去執行其他業務。
我沒有閱讀源碼,參考下面文章 Redis 網絡架構及單線程模型
總結壹下 :對於Redis的網絡請求,Redis會有壹個EventLoop,裏面有兩個數組events,fired。events存放被註冊的事件,fired用於存放EventLoop從 多路復用器 (epoll)中讀取到的,將要執行的事件。
異步和非阻塞就反映在這裏,註冊到 多路復用器 (epoll)後去做其他事,之後通過主動輪詢多路復用器,來逐個取出將要執行的事件,放入fired,逐個執行,這個過程是單線程的,因此不會出現並發問題。
問題三:什麽是多路復用?select 、poll、epoll的區別(待解決)
主要問題已經解決,這個問題等我整理好再發出來。