Redis是单线程为什么还那么快?
Redis為什么還那么快
基于內存
??Redis完全基于內存,絕大部分請求是純粹的內存操作,Redis將數據存儲在內存中,讀寫數據的時候不會受到硬盤I/O速度的限制(內存速度為什么比硬盤快?),類似于HashMap(HashMap的優勢就是查找和操作的時間復雜度都是O(1))。
單線程
??Redis采用單線程的模型,確保每個操作的原子性,避免不必要的上下文切換和競爭條件,自然也就不存在多進程或者多線程導致的切換而消耗CPU,也不用去考慮各種鎖的問題,不存在加解鎖的操作,所以沒有可能出現死鎖導致的性能消耗
使用多路復用
??Redis采用網絡IO多路復用技術來保證多鏈接的時候系統的高吞吐量??梢宰寙蝹€線程高效的處理多個鏈接請求,減少網絡IO時間消耗。主要是利用了select、poll、epoll可以同時監察多了IO時間的能力,一次順序的處理就緒的IO事件避免了大量的無用的操作,從而提高效率。
自己的事件分離器
??redis使用自己實現的事件分離器,效率比較高,內部采用非阻塞的執行方式,吞吐量能力比較大
靈活多變的數據結構
??redis內部使用一個redisObject對象來表示所有的key和calue。redisObject主要的信息包括數據類型、編碼方式、數據指針、虛擬內存等。主要包含string、Hash、List、Set、Sorted Set物種數據類型,針對不同的場景使用對應的數據類型,減少內存使用的同時,節省網絡流量的傳輸
Redis為什么是單線程?為什么不用多線程?
??首先需要明確的一點就是單線程指的是網絡請求模塊使用了一個線程,所以不需要考慮并發安全性,其他科模塊也會用到多線程,在使用redis的過程中充分的發揮其優勢,避免一些不當操作導致性能的下降。說redis是單線程只是在4.0版本之前,在4.0之后的版本中就加入了多線程的支持。Redis從一開始就使用單線程模型處理來自客戶端的網絡請求,其實原因是多方面的,重要的有三個:高可維護性、單線程也可以處理并發請求、性能瓶頸不是CPU
多線程模型雖然在某些方面變現優異,但是他的執行順序是不確定的,代碼的執行過程不再是串行的,并且多個線程同時訪問的變量如果沒有謹慎處理可能最后的結果會是不正確的
使用單線程并不代表不能并發處理任務,Redis雖然使用的是單線程模型處理用戶的請求,但他確實用I/O多路復用機制并發處理客戶端的多個鏈接。使用I/O多路復用技術能夠極大的減少系統的開銷,系統不在需要額外創建和維護進程和線程來監聽客戶端的大量鏈接,減少了服務器開發和維護的成本。
性能瓶頸是Redis選擇單線程模型的決定性原因。多線程技術確實能夠幫助我們充分的利用CPU的計算資源來并發的執行任務,但是CPU資源并不是Redis服務器的性能瓶頸。即使實在一個普通的linux中啟動Redis服務,也可以達到百萬QPS。
總結
??Redis并不是CPU密集型的服務,如果不持久化,所有的Redis數據都只會在內存中完成,并不會涉及到任何的I/O操作,所以處理速度是非常快的。Redis的瓶頸是在于網絡傳輸帶來的延遲和等待客戶端的數據傳輸(網絡I/O),所以使用多線程模型來處理全部的外部請求并不是一個很好的選擇。
??多線程雖然可以充分的利用CPU資源,但是在操作系統上的切換也會帶來額外的開銷,比如所加載和執行線程的上下文,頻繁的對線程上下文進行切換還會導致性能的急劇下降,可能會導致我們的優化進行倒退,這也是為什么Redis對于使用多線程技術的非常謹慎的原因。
??Redis在4.0后的版本中引入了多線程,加入了一些可以被其他線程異步處理的刪除操作(UNLINK、FLUSHALL ASYNC 和 FLUSHDB ASYNC)。在Redis中使用DEL命令刪除鍵對應的值,如果鍵占用的空間比較小,同步刪除并不會太耗時,但是針對一些超大的鍵值對,比如幾十或者幾百MB的數據并不能很快的處理完,就會消耗較多的時間,會影響到Redis服務處理請求的速度和可用性。其實這個釋放內存的工作可以交給后臺的多線程進行異步的處理,這就是UNLINK命令,他只是將鍵從元數據中刪除,其真正的刪除是在后臺異步進行。
??說了這么多,Redis選擇使用單線程模型處理客戶端的請求還是因為CPU不是Redis服務器的瓶頸,所以使用多線程模型可能會起到相反的效果,其主要的瓶頸是在網絡I/O上。Redis引入多線程主要是針對一些大的鍵值對的刪除操作,在后臺異步進行空間的釋放,減少對Redis主線程的阻塞,提高執行效率。
總結
以上是生活随笔為你收集整理的Redis是单线程为什么还那么快?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python二级基础知识点
- 下一篇: 【每日SQL打卡】