很久很久以前,在某公司的會議室裏正在進行一場面試…
面試官:看到你簡歷上寫着“熟練掌握Redis”,你說說對Redis的理解。
馬D梅:Redis作爲一款流行的緩存中間件,其顯著的性能是由於單進程單線程的設計…
面試官:等等,你說Redis是單進程單線程的?
馬D梅:這個…(我記得網上都是這麼說的…)
結論一:Redis並不是純粹的單進程單線程。
可能有小夥伴會有疑問,爲什麼會是這個結論?
舉個簡單的栗子就可以證明Redis並不單純是單進程單線程運行的。
我們都知道Redis有兩種持久化的方式,一種是RDB,一種是AOF。
拿RDB舉例,執行bgsave
,就意味着 fork 出一個子進程在後臺進行備份。
這也就爲什麼執行完bgsave
命令之後,還能對該Redis實例繼續其他的操作。
結論二:單線程指的是網絡請求模塊使用了一個線程(所以不需考慮併發安全性),即一個線程處理所有網絡請求,其他模塊仍用了多個線程。
爲了解釋爲什麼Redis以單線程的方式處理數據性能會比較高,這裏需要先講一點多線程的知識。
多線程並不一定意味着快。
上圖我們可以看到,這兩個線程所執行的任務都是計算型任務。
一個CPU處理多個請求會導致單個請求響應時間過長;而且頻繁切換線程上下文會增加性能損耗。
那爲什麼我們還總是使用多線程?
我們知道,大多數任務中都會涉及到網絡請求、IO讀取(包括文件、數據庫等)等操作,這些都會產生一定的阻塞問題,那麼這時候多線程就產生作用了。
當線程-3發生阻塞時,如果不進行切換,那就是白白佔用CPU的資源,此時CPU是空閒的;反之,切換到其他線程,CPU則執行其他線程的任務,不至於沒事情可幹、偷偷在摸魚。
這也就是爲什麼Redis處理大部分請求時都是單線程的,並因此獲得顯著的性能。就是因爲Redis處理的這些請求都是計算型,並且Redis是純內存操作,再加上帶有I/O多路複用功能。
純屬個人見解,如有錯誤,歡迎指出。