關(guān)于Redis單線程的正確理解
很多同學(xué)對Redis的單線程和I/O多路復(fù)用技術(shù)并不是很了解,所以我用簡單易懂的語言讓大家了解下Redis單線程和I/O多路復(fù)用技術(shù)的原理,對學(xué)好和運(yùn)用好Redis打下基礎(chǔ)。
一、Redis的單線程理解
Redis客戶端對服務(wù)端的每次調(diào)用都經(jīng)歷了發(fā)送命令,執(zhí)行命令,返回結(jié)果三個(gè)過程。其中執(zhí)行命令階段,由于Redis是單線程來處理命令的,所有到達(dá)服務(wù)端的命令都不會立刻執(zhí)行,所有的命令都會進(jìn)入一個(gè)隊(duì)列中,然后逐個(gè)執(zhí)行,并且多個(gè)客戶端發(fā)送的命令的執(zhí)行順序是不確定的,但是可以確定的是不會有兩條命令被同時(shí)執(zhí)行,不會產(chǎn)生并發(fā)問題,這就是Redis的單線程基本模型。
Redis服務(wù)器通過socket(套接字)與客戶端或其他Redis服務(wù)器進(jìn)行連接,而文件事件就是服務(wù)器對socket操作的抽象。服務(wù)器與客戶端或其他服務(wù)器的通信會產(chǎn)生相應(yīng)的文件事件,而服務(wù)器通過監(jiān)聽并處理這些事件來完成一系列網(wǎng)絡(luò)通信操作。
Redis基于Reactor模式開發(fā)了自己的網(wǎng)絡(luò)事件處理器——文件事件處理器,文件事件處理器使用I/O多路復(fù)用程序來同時(shí)監(jiān)聽多個(gè)socket(I/O多路復(fù)用技術(shù)下面有介紹),并根據(jù)socket目前執(zhí)行的任務(wù)來為socket關(guān)聯(lián)不同的事件處理器。當(dāng)被監(jiān)聽的socket準(zhǔn)備好執(zhí)行連接應(yīng)答、讀取、寫入、關(guān)閉等操作時(shí),與操作相對應(yīng)的文件事件就會產(chǎn)生,這時(shí)文件事件處理器就會調(diào)用socket之前已關(guān)聯(lián)好的事件處理器來處理這些事件。
文件事件處理器的構(gòu)成:

注意:其中I/O多路復(fù)用程序通過隊(duì)列向文件事件分派器傳送socket
二、I/O多路復(fù)用技術(shù)
關(guān)于I/O多路復(fù)用(又被稱為“事件驅(qū)動”),首先要理解的是,操作系統(tǒng)為你提供了一個(gè)功能,當(dāng)你的某個(gè)socket可讀或者可寫的時(shí)候,它可以給你一個(gè)通知。這樣當(dāng)配合非阻塞的socket使用時(shí),只有當(dāng)系統(tǒng)通知我哪個(gè)描述符可讀了,我才去執(zhí)行read操作,可以保證每次read都能讀到有效數(shù)據(jù)而不做純返回-1和EAGAIN的無用功,寫操作類似。
操作系統(tǒng)的這個(gè)功能是通過select/poll/epoll/kqueue之類的系統(tǒng)調(diào)用函數(shù)來實(shí)現(xiàn),這些函數(shù)都可以同時(shí)監(jiān)視多個(gè)描述符的讀寫就緒狀況,這樣,多個(gè)描述符的I/O操作都能在一個(gè)線程內(nèi)并發(fā)交替地順序完成,這就叫I/O多路復(fù)用,這里的“多路”指的是多個(gè)網(wǎng)絡(luò)連接,“復(fù)用”指的是復(fù)用同一個(gè)Redis處理線程。(正如上圖所示)
采用多路 I/O 復(fù)用技術(shù)可以讓單個(gè)線程高效的處理多個(gè)連接請求(盡量減少網(wǎng)絡(luò) I/O 的時(shí)間消耗),且 Redis 在內(nèi)存中操作數(shù)據(jù)的速度非??欤簿褪钦f內(nèi)存內(nèi)的操作不會成為影響Redis性能的瓶頸,所有 Redis 具有很高的吞吐量。
三、常見疑問解答
1、Redis的單線程為什么這么快?
1.完全基于內(nèi)存,絕大部分請求是純粹的內(nèi)存操作,非常快速。數(shù)據(jù)存在內(nèi)存中,類似于HashMap,HashMap的優(yōu)勢就是查找和操作的時(shí)間復(fù)雜度都是O(1);
2.數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單,Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進(jìn)行設(shè)計(jì)的;
3.采用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因?yàn)榭赡艹霈F(xiàn)死鎖而導(dǎo)致的性能消耗;
4.使用多路I/O復(fù)用模型,非阻塞I/O;
5.Redis直接自己構(gòu)建了VM 機(jī)制 ,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會浪費(fèi)一定的時(shí)間去移動和請求;
2、為什么不采用多進(jìn)程或多線程處理?
1.多線程處理可能涉及到鎖
2.多線程處理會涉及到線程切換而消耗CPU
3、單線程處理的缺點(diǎn)?
1.耗時(shí)的命令會導(dǎo)致并發(fā)的下降,不只是讀并發(fā),寫并發(fā)也會下降
2.無法發(fā)揮多核CPU性能,不過可以通過在單機(jī)開多個(gè)Redis實(shí)例來完善
4、Redis不存在線程安全問題?
Redis采用了線程封閉的方式,把任務(wù)封閉在一個(gè)線程,自然避免了線程安全問題,不過對于需要依賴多個(gè)redis操作(即:多個(gè)Redis操作命令)的復(fù)合操作來說,依然需要鎖,而且有可能是分布式鎖。
到此這篇關(guān)于Redis單線程的正確理解的文章就介紹到這了,更多相關(guān)Redis單線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot中redis并發(fā)鎖的等待時(shí)間設(shè)置長短的方法
在SpringBoot應(yīng)用中,Redis鎖的等待時(shí)間設(shè)置不當(dāng)可能導(dǎo)致資源浪費(fèi)、響應(yīng)時(shí)間增加、死鎖風(fēng)險(xiǎn)升高、系統(tǒng)負(fù)載增加、業(yè)務(wù)邏輯延遲以及故障恢復(fù)慢等問題,建議合理設(shè)置等待時(shí)間,并考慮使用其他分布式鎖實(shí)現(xiàn)方式提高性能2024-10-10
使用redis-plus-plus庫連接redis的實(shí)現(xiàn)方法
本文主要介紹了使用redis-plus-plus庫連接redis的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
Redis實(shí)戰(zhàn)之Redis實(shí)現(xiàn)異步秒殺優(yōu)化詳解
這篇文章主要給大家介紹了Redis實(shí)戰(zhàn)之Redis實(shí)現(xiàn)異步秒殺優(yōu)化方法,文章通過圖片和代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以自己動手試一下2023-09-09
Redis和Lua實(shí)現(xiàn)分布式限流器的方法詳解
這篇文章主要給大家介紹了關(guān)于Redis和Lua實(shí)現(xiàn)分布式限流器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Redis和Lua具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
redis使用不當(dāng)導(dǎo)致應(yīng)用卡死bug的過程解析
本文主要記一次找因redis使用不當(dāng)導(dǎo)致應(yīng)用卡死bug的過程,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
Redis 事務(wù)知識點(diǎn)相關(guān)總結(jié)
這篇文章主要介紹了Redis 事務(wù)相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Redis,感興趣的朋友可以了解下2021-03-03
?Redis 串行生成順序編碼的方法實(shí)現(xiàn)
本文主要介紹了?Redis 串行生成順序編碼的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Redis實(shí)現(xiàn)優(yōu)惠券限一單限制詳解
這篇文章主要介紹了Redis解決優(yōu)惠券秒殺應(yīng)用案例,本文先講了搶購問題,指出其中會出現(xiàn)的多線程問題,提出解決方案采用悲觀鎖和樂觀鎖兩種方式進(jìn)行實(shí)現(xiàn),然后發(fā)現(xiàn)在搶購過程中容易出現(xiàn)一人多單現(xiàn)象,需要的朋友可以參考下2022-12-12

