這篇文章將為大家詳細講解有關Redis使用單線程為什么還這么快,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
通常情況下,在采用多線程后,如果沒有良好的系統設計,其實是右圖所展示的那樣(注意縱坐標)。剛開始增加線程數時,系統吞吐率會增加,再進一步增加線程時,系統吞吐率就增長遲緩了,甚至還會出現下降的情況。

關鍵瓶頸在于: 系統中通常會存在會被多線程同時訪問的共享資源,為了保證共享資源的正確性,就需要有額外的機制保證線程安全性,例如加鎖,這會帶來額外的開銷。
比如拿最常用的List類型來舉例吧,假設Redis采用多線程設計,有兩個線程A和B分別對List做LPUSH和LPUSH操作,為了使得每次執行都是相同的結果,即【B線程取出A線程放入的數據】就需要讓這兩個過程串行執行。這就是多線程編程模式面臨的共享資源的并發訪問控制問題。

并發訪問控制一直是多線程開發中的一個難點問題:如果只是簡單地采用一個互斥鎖,就會出現即使增加了線程,大部分線程也在等待獲取互斥鎖,并行變串行,系統吞吐率并沒有隨著線程的增加而增加。
同時加入并發訪問控制后也會降低系統代碼的可讀性和可維護性,所以Redis干脆直接采用了單線程模式。
之所以使用單線程是Redis設計者多方面衡量的結果。
Redis的大部分操作在內存上完成
采用了高效的數據結構,例如哈希表和跳表
采用了多路復用機制,使其在網絡IO操作中能并發處理大量的客戶端請求,實現高吞吐率
既然Redis使用單線程進行IO,如果線程被阻塞了就無法進行多路復用了,所以不難想象,Redis肯定還針對網絡和IO操作的潛在阻塞點進行了設計。
在網絡通信里,服務器為了處理一個Get請求,需要監聽客戶端請求(bind/listen),和客戶端建立連接(accept),從socket中讀取請求(recv),解析客戶端發送請求(parse),最后給客戶端返回結果(send)。
最基本的一種單線程實現是依次執行上面的操作。

上面標紅的accept和recv操作都是潛在的阻塞點:
當Redis監聽到有連接請求,但卻一直不能成功建立起連接時,就會阻塞在accept()函數這里,其他客戶端此時也無法和Redis建立連接
當Redis通過recv()從一個客戶端讀取數據時,如果數據一直沒有到達,也會一直阻塞
為了解決IO中的阻塞問題,Redis采用了Linux的IO多路復用機制,該機制允許內核中,同時存在多個監聽套接字和已連接套接字(select/epoll)。
內核會一直監聽這些套接字上的連接或數據請求。一旦有請求到達,就會交給Redis處理,這就實現了一個Redis線程處理多個IO流的效果。

此時,Redis線程就不會阻塞在某一個特定的客戶端請求處理上,所以它可以同時和多個客戶端連接并處理請求。
select/epoll一旦監測到FD上有請求到達時,就會觸發相應的事件被放進一個隊列里,Redis線程對該事件隊列不斷進行處理,所以就實現了基于事件的回調。
例如,Redis會對Accept和Read事件注冊accept和get回調函數。當Linux內核監聽到有連接請求或讀數據請求時,就會觸發Accept事件和Read事件,此時,內核就會回調Redis相應的accept和get函數進行處理。
經過上面的分析,雖然通過多路復用機制可以同時監聽多個客戶端的請求,但Redis仍然有一些性能瓶頸點,這也是我們平時編程需要極力避免的情況。
任意一個請求在Redis中一旦耗時較久,都會影響整個server的性能。后面的請求都要等前面這個耗時請求處理完成,自己才能被處理到。
這一點需要我們在設計業務場景時去規避;Redis的lazy-free機制也把釋放內存的耗時操作放在了異步線程中去執行了。
并發量非常大時,單線程讀寫客戶端IO數據存在性能瓶頸,雖然采用IO多路復用機制,但還是只能單線程依次讀取客戶端的數據,無法利用到CPU多核。
Redis在6.0可以利用CPU多核多線程讀寫客戶端數據,但只是針對客戶端的讀寫是并行的,每個命令的真正操作還是單線程。
借此機會也提幾個和redis相關的有意思的問題。

為什么要用Redis,直接訪問內存不好嗎?
這一條其實并沒有很明確的界定,對于一些不經常變動的數據,可以直接放到內存里,不一定要放到Redis里,可以放到內存里。一致性問題:如果一個數據被修改了,數據在本地內存里的話,可能只有一臺服務器上的數據被修改了。如果用Redis里面的話,我們訪問Redis服務器,可以解決一致性問題。
數據太多內存放不下怎么辦?比如我要緩存100G的數據,怎么辦?
這里也要打一個廣告Tair是淘寶開源的分布式KV緩存系統,它從Redis繼承了豐富的操作,理論上總數據量無限制,針對可用性、可擴展性、可靠性也進行了升級,感興趣的小伙伴們可以了解一下~
關于“Redis使用單線程為什么還這么快”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。