本篇文章給大家?guī)砹岁P(guān)于redis的相關(guān)知識(shí),其中主要介紹了關(guān)于線程模型的相關(guān)問題,redis它是一個(gè)單線程的,下面就一起來看一下,希望對(duì)大家有幫助。
推薦學(xué)習(xí):redis
redis它是一個(gè)單線程的,這一點(diǎn)需要去注意的。
首先我們呢會(huì)有一個(gè)客戶端,這個(gè)客戶端在我們之前其實(shí)使用的是一個(gè)redis client 這樣的一個(gè)工具去連接的redis server。
如果說我們后續(xù)再整合到Java 里面去的話,在java 里面其實(shí)也會(huì)提供相應(yīng)的客戶端的。
隨后我們會(huì)有一個(gè)redis server,這個(gè)其實(shí)就是我們的一個(gè)redis,它整個(gè)服務(wù)在啟動(dòng)以后,它是會(huì)有一個(gè)進(jìn)程的。
在我們的release 里面,在內(nèi)部它其實(shí)會(huì)有兩個(gè)東西。
首先一個(gè)它會(huì)有一個(gè)多路復(fù)用器,這個(gè)我們上節(jié)課已經(jīng)是介紹過了,它是非阻塞的一個(gè)模型。
隨后它其實(shí)還會(huì)有一個(gè)文件事件分配器,它專門是用于去分配一些事件的。
在這個(gè)下面,它會(huì)分為三個(gè)不同的處理器,分別來看一下。
首先呢有一個(gè)連接應(yīng)答處理器,最后的是一個(gè)命令請(qǐng)求處理器,還有是一個(gè)命令回復(fù)處理器。
如何去理解呢?首先我們先來看一個(gè)連接應(yīng)答處理器。
連接應(yīng)答處理器的話,它的一個(gè)主要作用是要和我們的客戶端去保持一個(gè)鏈接。
像我們的一個(gè)redis server一旦啟動(dòng)了以后,其實(shí)呢我們就會(huì)有read 的這樣的一個(gè)事件和我們的連接應(yīng)答器會(huì)捆綁到一起。
它的全稱其實(shí)叫做AE_readable。你就可以把它理解為是一種標(biāo)志啊,它會(huì)有這樣的一個(gè)事件,這個(gè)事件是會(huì)和我們的連接應(yīng)答處理器捆綁到一起的。
最后當(dāng)我們的一個(gè)客戶端和咱們的server 要去建立連接的時(shí)候,這個(gè)其實(shí)也就是我們?cè)谝婚_始在命令行工具里面敲下了一個(gè)redis client,一開始的話肯定是需要和我們的server 去建立連接嘛。建立連接的時(shí)候,他其實(shí)就會(huì)發(fā)送一個(gè)read 標(biāo)志,其實(shí)就是一個(gè)read 的時(shí)間,這個(gè)時(shí)候的話,在我們的redis server 里面,它其實(shí)會(huì)有一個(gè)叫做server socket。
server socket 和我們的一個(gè)客戶端socket 其實(shí)是對(duì)應(yīng)的,他們是屬于網(wǎng)絡(luò)編程里面的一塊內(nèi)容,他們之間是一個(gè)socket 的通信。在我們接觸到read 這樣的一個(gè)事件了以后,隨后我們呢就會(huì)交由咱們的多路復(fù)用器去進(jìn)行處理吧。
交給他去處理以后的話,其實(shí)他是一個(gè)非阻塞的,拿到了以后一旦接收,他就會(huì)把它放到我們這樣的一個(gè)箭頭里面去。
這個(gè)箭頭的話在這邊其實(shí)我們可以稱之為它是一個(gè)管道pipeline,或者我們也可以把它稱之為是一個(gè)隊(duì)列。它會(huì)往這里面丟,丟進(jìn)去以后,這個(gè)世界呢其實(shí)就會(huì)到達(dá)我們的文件事件分配器。這個(gè)分配器當(dāng)它識(shí)別到它是一個(gè)read 這樣的事件以后,它就會(huì)和我們的這個(gè)連接應(yīng)答處理器去做到一個(gè)匹配,也就是交由它去進(jìn)行一個(gè)處理。
它是一個(gè)read 相互進(jìn)行一個(gè)匹配。
這個(gè)時(shí)候的話其實(shí)就可以表明咱們的client 和server 這兩端就是建立了一個(gè)連接。建立好連接了以后這個(gè)read 標(biāo)識(shí)的話,這個(gè)事件它其實(shí)就會(huì)交由給我們的命令請(qǐng)求處理器。這個(gè)命令請(qǐng)求處理器的話,你就可以認(rèn)為它是專門去處理請(qǐng)求的,也就是一個(gè)request。然后命令回復(fù)處理器,你可以把它理解為是一個(gè)response,也就是一個(gè)響應(yīng)。
隨后我們?cè)诳蛻舳丝赡芤ィ确秸f我們要去set 一個(gè)值,對(duì)吧?set 一個(gè)值的話,比方說set name *** 這樣子的話,其實(shí)它是一個(gè)命令嘛。
這個(gè)命令的話它的一個(gè)世界類型其實(shí)也是一個(gè)read。隨后呢經(jīng)過server socket 再丟給多路復(fù)用器,拿到以后放到咱們的隊(duì)列里面去再交由文件事件分配器。
這個(gè)文件事件分配器拿到以后,它會(huì)進(jìn)行一個(gè)判斷吧,它會(huì)判斷匹配是read的事件。它這個(gè)時(shí)候是一個(gè)read的事件的時(shí)候,就會(huì)讓我們的命令請(qǐng)求處理器去處理咱們的命令。他就會(huì)去識(shí)別了呀,他會(huì)去識(shí)別當(dāng)前就是一個(gè)set name ***,所以他就要去做一個(gè)處理。他要把我們用戶所設(shè)置的一個(gè)內(nèi)容,把這個(gè)鍵值做一個(gè)存儲(chǔ),存儲(chǔ)到咱們的內(nèi)存里面去。這個(gè)其實(shí)就是一個(gè)命令請(qǐng)求的處理,就是一個(gè)request 。
當(dāng)它處理完畢以后,隨后的話它會(huì)分配一個(gè)white,也就是寫的一個(gè)標(biāo)識(shí)。這個(gè)寫的標(biāo)識(shí)的話,在這邊的話,其實(shí)呢我們就可以把它作為響應(yīng)。因?yàn)槲覀兊囊粋€(gè)請(qǐng)求其實(shí)在處理完畢之后,在我們輸入完畢一個(gè)命令以后,可能會(huì)看到一個(gè)ok 對(duì)吧?這個(gè)ok 的話其實(shí)就相當(dāng)于是我們的一個(gè)命令回復(fù)處理器回寫給我們的一個(gè)內(nèi)容。所以他會(huì)用到一個(gè)write寫的一個(gè)標(biāo)記。這樣子我們的一個(gè)寫的標(biāo)記其實(shí)是會(huì)和我們命令回復(fù)處理器是捆在一起的。write 的話,其實(shí)它的全稱是叫做AE_writable 這樣的一個(gè)事件類型的。
好,隨后在我們的客戶端這個(gè)地方,其實(shí)我們就需要去做一個(gè)回寫也。就是ok 或者說我們?cè)诓樵僱ist,我們要展示list 里面所有的內(nèi)容的時(shí)候,它其實(shí)是回寫的一個(gè)情況。我們要把內(nèi)容顯示在控制臺(tái)的下方,它是一個(gè)write 這樣的一個(gè)事件類型。隨后交由我們的多路復(fù)用器再丟給咱們的一個(gè)隊(duì)列,讓這個(gè)隊(duì)列分配給我們的一個(gè)文件事件分配器的。這個(gè)時(shí)候會(huì)匹配咱們的web 事件。web 事件是匹配到了。
隨后的話,我們的命令回復(fù)處理器就會(huì)做一個(gè)回寫。它會(huì)把我們的ok 啊或者說是我們的一個(gè)獲得的一個(gè)list 數(shù)量,list 里面的內(nèi)容等等。只要是一些需要展示的內(nèi)容,他都會(huì)是作為一個(gè)response,就是把這個(gè)響應(yīng)的內(nèi)容回寫給我們的一個(gè)客戶端,在客戶端上進(jìn)行一個(gè)展示。在我們當(dāng)前這整個(gè)模型里面的話,其實(shí)主要就是兩個(gè)不同的事件,一個(gè)叫做readable 的,一個(gè)叫做writable 。
當(dāng)然我們現(xiàn)在設(shè)置的僅僅只是一個(gè)客戶端,如果說我們會(huì)有多個(gè)客戶端的話,他們的道理也都是一模一樣的。這個(gè)其實(shí)就是release 的一個(gè)線程模型。初次接觸的話是可能會(huì)比較的難以去理解,但是沒有關(guān)系的。這張圖的話其實(shí)也是可以輔助大家去加深這個(gè)意向。
然后他整個(gè)處理的流程,也是可以跟著我所說的進(jìn)行理解。為了便于大家的一個(gè)理解,我們?cè)谶@里畫一個(gè)圖啊,來做一個(gè)舉例。
假設(shè)我們現(xiàn)在呢有一個(gè)KTV,這個(gè)KTV就是redis。
然后呢我們有很多的顧客要去唱歌,要去唱歌的話,我們KTV里面肯定會(huì)有員工嘛,員工的話我們會(huì)分為兩大類。
第一個(gè)大類是門口的接待員,第二個(gè)是大堂經(jīng)理。
門口的接待員其實(shí)他就是一個(gè)多路復(fù)用器,大堂經(jīng)理的話其實(shí)就是一個(gè)文件分配器。
然后呢,我們的顧客肯定是有一些相應(yīng)的請(qǐng)求吧,或者說是相應(yīng)的需求,這個(gè)時(shí)候肯定是要詢問我們的門口的接待員,讓門口的接待員去做簡單的一些處理。
可能他要去看一下這個(gè)用戶想要去參加什么樣的活動(dòng),有沒有優(yōu)惠券等等。
然后門口的接單員,如果說確定這個(gè)顧客要去唱歌的話,就可以說請(qǐng)往后面走,后面有一個(gè)通道。這個(gè)通道的話其實(shí)就是一個(gè)隊(duì)列,你們排著隊(duì)往這個(gè)通道走。走到里面的話,就是我們整個(gè)KTV的一個(gè)營業(yè)廳了。到營業(yè)廳里面它會(huì)有一個(gè)大堂經(jīng)理,大堂經(jīng)理的話會(huì)去處理我們的一個(gè)顧客真實(shí)的請(qǐng)求。
隨后在我們的一個(gè)KTV里面,其實(shí)我們的肯定會(huì)有一個(gè)包廂,每一個(gè)包廂的話是會(huì)去處理用戶,去處理顧客不同的請(qǐng)求的了。在我們的這個(gè)包廂的內(nèi)部呢,會(huì)有三個(gè)小姐姐或者小哥哥,他們呢是會(huì)為用戶去處理不同的一些需求的。
比方說第一個(gè)的話,他就專門是為顧客去開門的。開門這個(gè)動(dòng)作就相當(dāng)于是我們的一個(gè)客戶端和release 去建立了一個(gè)鏈接。門打開以后,你就可以進(jìn)來了,對(duì)吧?進(jìn)來以后的話,這個(gè)小姐姐就不負(fù)責(zé)他相應(yīng)的一些工作了,他就會(huì)把他交給我們的下面的一個(gè)人,下面的一個(gè)小姐姐或者小哥哥,就是專門為用戶去處理一些請(qǐng)求的。
比方說某一個(gè)顧客要點(diǎn)歌的,這個(gè)時(shí)候就會(huì)讓點(diǎn)歌的人做一些相應(yīng)的處理。這個(gè)處理的話就是打開電腦去點(diǎn)歌選歌。選完歌了以后,你得要響應(yīng)給顧客吧。你有沒有點(diǎn)好,對(duì)吧?你還要把一些話筒麥克風(fēng)遞給顧客,所以這個(gè)時(shí)候會(huì)有一個(gè)通知,有這樣的一個(gè)小姐姐,這個(gè)小姐姐會(huì)把這個(gè)麥克風(fēng)給到顧客。你現(xiàn)在可以去唱歌了,我們這個(gè)歌已經(jīng)是為你點(diǎn)好了,你去唱吧。
這個(gè)時(shí)候其實(shí)就完成了一個(gè)顧客在KTV里面點(diǎn)歌唱歌這一整個(gè)動(dòng)作。這個(gè)其實(shí)也就是對(duì)應(yīng)在我們之前,我們?cè)趓elease 這個(gè)線程模型里面所提及的某一個(gè)客戶端執(zhí)行的一個(gè)操作吧。首先是建立連接,然后呢去處理請(qǐng)求,隨后呢去響應(yīng)他的一個(gè)請(qǐng)求。這個(gè)總共這里是有三步操作。
在我們這一塊里面的話,整個(gè)大堂經(jīng)理以及是他們點(diǎn)歌通知這一系列的操作的話,其實(shí)都是在我們的內(nèi)部去做處理的。也就是基于我們的一個(gè)包廂。包廂的話,在我們的redis里面,咱們是不是可以把它作為是一個(gè)內(nèi)存啊,因?yàn)閞edis一個(gè)存儲(chǔ)讀取等等的操作,其實(shí)都是基于內(nèi)存的。所以在內(nèi)存里面的話它是非常的快的。
在我們的包廂里面的話,包廂里面你不管是去唱歌還是點(diǎn)一些水果啊,喝一些啤酒啊等等。其實(shí)都是基于我們內(nèi)部的一個(gè)包廂去做操作的話,它的一系列的動(dòng)作等等的話,完成度其實(shí)也是非常的快的。
這個(gè)其實(shí)就可以為了我們的一個(gè)線程模型去做了樸素的理解。對(duì)于我們的redis 來講的話,它其實(shí)是一個(gè)單線程模式。為什么使用單線程模型會(huì)非常的快呢?
其實(shí)主要是有兩點(diǎn)。
第一點(diǎn)的話是我們的一個(gè)門口的接待員,其實(shí)也就是一個(gè)多路復(fù)用器。這個(gè)多路復(fù)用器的話,它是基于一個(gè)非阻塞的模型,所以呢它處理起來是非常的快的。它不會(huì)因?yàn)橐郧暗囊环N阻塞模式,而一個(gè)一個(gè)的去等待去響應(yīng)。現(xiàn)在使用了一個(gè)IO多路復(fù)用器這樣的模型以后,其實(shí)它的一個(gè)處理效能是非常非常的快的。
另外一部分就是我們的大堂經(jīng)理這一塊,這一塊其實(shí)它是基于內(nèi)存去做操作的。純內(nèi)存的操作的話,其實(shí)它是會(huì)非常非常的快的。
當(dāng)然使用了單線程以后,其實(shí)它的一個(gè)作用也說了,使用單線程的話,它是可以避免在多線程的時(shí)候。因?yàn)槟愣嗑€程的話,你有可能會(huì)使用到它的一個(gè)上下文的一個(gè)切換。一旦切換的話,有可能會(huì)引起一些問題。另外呢也是可以避免一些相應(yīng)的損耗的。所以當(dāng)我們?cè)谑褂酶删€模型的時(shí)候,它的一個(gè)并發(fā)性,它的效率是非常非常的高的。
推薦學(xué)習(xí):redis