相關視訊教程(來自動力節點)
相關資料下載下傳
很多開發者對Redis的單線程和I/O多路複用技術并不是很了解,是以我用簡單易懂的語言讓大家了解下Redis單線程和I/O多路複用技術的原理,對學好和運用好Redis打下基礎。
Redis用戶端對服務端的每次調用都經曆了發送指令,執行指令,傳回結果三個過程。其中執行指令階段,由于Redis是單線程來處理指令的,所有到達服務端的指令都不會立刻執行,所有的指令都會進入一個隊列中,然後逐個執行,并且多個用戶端發送的指令的執行順序是不确定的,但是可以确定的是不會有兩條指令被同時執行,不會産生并發問題,這就是Redis的單線程基本模型。
Redis伺服器通過socket(套接字)與用戶端或其他Redis伺服器進行連接配接,而檔案事件就是伺服器對socket操作的抽象。伺服器與用戶端或其他伺服器的通信會産生相應的檔案事件,而伺服器通過監聽并處理這些事件來完成一系列網絡通信操作。
Redis基于Reactor模式開發了自己的網絡事件處理器——檔案事件處理器,檔案事件處理器使用I/O多路複用程式來同時監聽多個socket(I/O多路複用技術下面有介紹),并根據socket目前執行的任務來為socket關聯不同的事件處理器。當被監聽的socket準備好執行連接配接應答、讀取、寫入、關閉等操作時,與操作相對應的檔案事件就會産生,這時檔案事件處理器就會調用socket之前已關聯好的事件處理器來處理這些事件。
關于I/O多路複用(又被稱為“事件驅動”),首先要了解的是,作業系統為你提供了一個功能,當你的某個socket可讀或者可寫的時候,它可以給你一個通知。這樣當配合非阻塞的socket使用時,隻有當系統通知我哪個描述符可讀了,我才去執行read操作,可以保證每次read都能讀到有效資料而不做純傳回-1和EAGAIN的無用功,寫操作類似。
作業系統的這個功能是通過select/poll/epoll/kqueue之類的系統調用函數來實作,這些函數都可以同時監視多個描述符的讀寫就緒狀況,這樣,多個描述符的I/O操作都能在一個線程内并發交替地順序完成,這就叫I/O多路複用,這裡的“多路”指的是多個網絡連接配接,“複用”指的是複用同一個Redis處理線程。
采用多路 I/O 複用技術可以讓單個線程高效的處理多個連接配接請求(盡量減少網絡 I/O 的時間消耗),且 Redis 在記憶體中操作資料的速度非常快,也就是說記憶體内的操作不會成為影響Redis性能的瓶頸,所有 Redis 具有很高的吞吐量。
1、Redis的單線程為什麼這麼快?
完全基于記憶體,絕大部分請求是純粹的記憶體操作,非常快速。資料存在記憶體中,類似于HashMap,HashMap的優勢就是查找和操作的時間複雜度都是O(1);
資料結構簡單,對資料操作也簡單,Redis中的資料結構是專門進行設計的;
采用單線程,避免了不必要的上下文切換和競争條件,也不存在多程序或者多線程導緻的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導緻的性能消耗;
使用多路I/O複用模型,非阻塞I/O;
Redis直接自己建構了VM 機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求;
2、為什麼不采用多程序或多線程處理?
多線程處理可能涉及到鎖
多線程處理會涉及到線程切換而消耗CPU
3、單線程處理的缺點?
耗時的指令會導緻并發的下降,不隻是讀并發,寫并發也會下降
無法發揮多核CPU性能,不過可以通過在單機開多個Redis執行個體來完善
4、Redis不存線上程安全問題?
Redis采用了線程封閉的方式,把任務封閉在一個線程,自然避免了線程安全問題,不過對于需要依賴多個redis操作(即:多個Redis操作指令)的複合操作來說,依然需要鎖,而且有可能是分布式鎖。
以上就是Redis的單線程和I/O多路複用技術的了解,下篇文章再說說Redis持久化RDB和AOF優缺點,如果對你有幫助,小夥伴們一定點贊支援哦~