日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

來源:全菜工程師小輝

文件事件處理器

redis基于Reactor模式開發(fā)了網(wǎng)絡(luò)事件處理器,這個(gè)處理器被稱為文件事件處理器。 它的組成結(jié)構(gòu)為4部分: 多個(gè)套接字、IO多路復(fù)用程序、文件事件分派器、事件處理器。 因?yàn)槲募录峙善麝?duì)列的消費(fèi)是單線程的,所以Redis才叫單線程模型。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

消息處理流程

  • 文件事件處理器使用I/O多路復(fù)用(multiplexing)程序來同時(shí)監(jiān)聽多個(gè)套接字,并根據(jù)套接字目前執(zhí)行的任務(wù)來為套接字關(guān)聯(lián)不同的事件處理器。
  • 當(dāng)被監(jiān)聽的套接字準(zhǔn)備好執(zhí)行連接應(yīng)答(accept)、讀取(read)、寫入(write)、關(guān)閉(close)等操作時(shí),與操作相對(duì)應(yīng)的文件事件就會(huì)產(chǎn)生,這時(shí)文件事件處理器就會(huì)調(diào)用套接字之前關(guān)聯(lián)好的事件處理器來處理這些事件。

盡管多個(gè)文件事件可能會(huì)并發(fā)地出現(xiàn),但I(xiàn)/O多路復(fù)用程序總是會(huì)將所有產(chǎn)生事件的套接字都推到一個(gè)隊(duì)列里面,然后通過這個(gè)隊(duì)列,以有序(sequentially)、同步(synchronously)、每次一個(gè)套接字的方式向文件事件分派器傳送套接字: 當(dāng)上一個(gè)套接字產(chǎn)生的事件被處理完畢之后(該套接字為事件所關(guān)聯(lián)的事件處理器執(zhí)行完畢), I/O多路復(fù)用程序才會(huì)繼續(xù)向文件事件分派器傳送下一個(gè)套接字。

I/O 多路復(fù)用程序的實(shí)現(xiàn)

Redis的I/O多路復(fù)用程序的所有功能是通過包裝select、epoll、evport和kqueue這些I/O多路復(fù)用函數(shù)庫來實(shí)現(xiàn)的,每個(gè)I/O多路復(fù)用函數(shù)庫在Redis源碼中都對(duì)應(yīng)一個(gè)單獨(dú)的文件,比如ae_select.c、ae_epoll.c、ae_kqueue.c等。

因?yàn)镽edis為每個(gè)I/O多路復(fù)用函數(shù)庫都實(shí)現(xiàn)了相同的API,所以I/O多路復(fù)用程序的底層實(shí)現(xiàn)是可以互換的,如下圖所示。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

有關(guān)epoll的詳細(xì)講解,可以點(diǎn)擊查看, 徹底搞懂epoll高效運(yùn)行的原理

Redis在I/O多路復(fù)用程序的實(shí)現(xiàn)源碼中用#include宏定義了相應(yīng)的規(guī)則,程序會(huì)在編譯時(shí)自動(dòng)選擇系統(tǒng)中性能最好的I/O多路復(fù)用函數(shù)庫來作為Redis的I/O多路復(fù)用程序的底層實(shí)現(xiàn):

/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
 #ifdef HAVE_EPOLL
 #include "ae_epoll.c"
 #else
 #ifdef HAVE_KQUEUE
 #include "ae_kqueue.c"
 #else
 #include "ae_select.c"
 #endif
 #endif
#endif

文件事件的類型

I/O 多路復(fù)用程序可以監(jiān)聽多個(gè)套接字的ae.h/AE_READABLE事件和ae.h/AE_WRITABLE事件,這兩類事件和套接字操作之間的對(duì)應(yīng)關(guān)系如下:

  • 當(dāng)套接字變得可讀時(shí)(客戶端對(duì)套接字執(zhí)行write操作,或者執(zhí)行close操作),或者有新的可應(yīng)答(acceptable)套接字出現(xiàn)時(shí)(客戶端對(duì)服務(wù)器的監(jiān)聽套接字執(zhí)行connect操作),套接字產(chǎn)生AE_READABLE 事件。
  • 當(dāng)套接字變得可寫時(shí)(客戶端對(duì)套接字執(zhí)行read操作),套接字產(chǎn)生AE_WRITABLE事件。I/O多路復(fù)用程序允許服務(wù)器同時(shí)監(jiān)聽套接字的AE_READABLE事件和AE_WRITABLE事件,如果一個(gè)套接字同時(shí)產(chǎn)生了這兩種事件,那么文件事件分派器會(huì)優(yōu)先處理AE_READABLE事件,等到AE_READABLE事件處理完之后,才處理AE_WRITABLE 事件。這也就是說,如果一個(gè)套接字又可讀又可寫的話,那么服務(wù)器將先讀套接字,后寫套接字。

文件事件的處理器

Redis為文件事件編寫了多個(gè)處理器,這些事件處理器分別用于實(shí)現(xiàn)不同的網(wǎng)絡(luò)通訊需求,常用的處理器如下:

  • 為了對(duì)連接服務(wù)器的各個(gè)客戶端進(jìn)行應(yīng)答, 服務(wù)器要為監(jiān)聽套接字關(guān)聯(lián)連接應(yīng)答處理器。
  • 為了接收客戶端傳來的命令請(qǐng)求, 服務(wù)器要為客戶端套接字關(guān)聯(lián)命令請(qǐng)求處理器。
  • 為了向客戶端返回命令的執(zhí)行結(jié)果, 服務(wù)器要為客戶端套接字關(guān)聯(lián)命令回復(fù)處理器。

連接應(yīng)答處理器

networking.c中acceptTcpHandler函數(shù)是Redis的連接應(yīng)答處理器,這個(gè)處理器用于對(duì)連接服務(wù)器監(jiān)聽套接字的客戶端進(jìn)行應(yīng)答,具體實(shí)現(xiàn)為sys/socket.h/accept函數(shù)的包裝。

當(dāng)Redis服務(wù)器進(jìn)行初始化的時(shí)候,程序會(huì)將這個(gè)連接應(yīng)答處理器和服務(wù)器監(jiān)聽套接字的AE_READABLE事件關(guān)聯(lián)起來,當(dāng)有客戶端用sys/socket.h/connect函數(shù)連接服務(wù)器監(jiān)聽套接字的時(shí)候, 套接字就會(huì)產(chǎn)生AE_READABLE 事件, 引發(fā)連接應(yīng)答處理器執(zhí)行, 并執(zhí)行相應(yīng)的套接字應(yīng)答操作,如圖所示。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

命令請(qǐng)求處理器

networking.c中readQueryFromClient函數(shù)是Redis的命令請(qǐng)求處理器,這個(gè)處理器負(fù)責(zé)從套接字中讀入客戶端發(fā)送的命令請(qǐng)求內(nèi)容, 具體實(shí)現(xiàn)為unistd.h/read函數(shù)的包裝。

當(dāng)一個(gè)客戶端通過連接應(yīng)答處理器成功連接到服務(wù)器之后, 服務(wù)器會(huì)將客戶端套接字的AE_READABLE事件和命令請(qǐng)求處理器關(guān)聯(lián)起來,當(dāng)客戶端向服務(wù)器發(fā)送命令請(qǐng)求的時(shí)候,套接字就會(huì)產(chǎn)生 AE_READABLE事件,引發(fā)命令請(qǐng)求處理器執(zhí)行,并執(zhí)行相應(yīng)的套接字讀入操作,如圖所示。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

在客戶端連接服務(wù)器的整個(gè)過程中,服務(wù)器都會(huì)一直為客戶端套接字的AE_READABLE事件關(guān)聯(lián)命令請(qǐng)求處理器。

命令回復(fù)處理器

networking.c中sendReplyToClient函數(shù)是Redis的命令回復(fù)處理器,這個(gè)處理器負(fù)責(zé)將服務(wù)器執(zhí)行命令后得到的命令回復(fù)通過套接字返回給客戶端,具體實(shí)現(xiàn)為unistd.h/write函數(shù)的包裝。

當(dāng)服務(wù)器有命令回復(fù)需要傳送給客戶端的時(shí)候,服務(wù)器會(huì)將客戶端套接字的AE_WRITABLE事件和命令回復(fù)處理器關(guān)聯(lián)起來,當(dāng)客戶端準(zhǔn)備好接收服務(wù)器傳回的命令回復(fù)時(shí),就會(huì)產(chǎn)生AE_WRITABLE事件,引發(fā)命令回復(fù)處理器執(zhí)行,并執(zhí)行相應(yīng)的套接字寫入操作, 如圖所示。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

當(dāng)命令回復(fù)發(fā)送完畢之后, 服務(wù)器就會(huì)解除命令回復(fù)處理器與客戶端套接字的 AE_WRITABLE 事件之間的關(guān)聯(lián)。

一次完整的客戶端與服務(wù)器連接事件示例

假設(shè)Redis服務(wù)器正在運(yùn)作,那么這個(gè)服務(wù)器的監(jiān)聽套接字的AE_READABLE事件應(yīng)該正處于監(jiān)聽狀態(tài)之下,而該事件所對(duì)應(yīng)的處理器為連接應(yīng)答處理器。

如果這時(shí)有一個(gè)Redis客戶端向Redis服務(wù)器發(fā)起連接,那么監(jiān)聽套接字將產(chǎn)生AE_READABLE事件, 觸發(fā)連接應(yīng)答處理器執(zhí)行: 處理器會(huì)對(duì)客戶端的連接請(qǐng)求進(jìn)行應(yīng)答, 然后創(chuàng)建客戶端套接字,以及客戶端狀態(tài),并將客戶端套接字的 AE_READABLE 事件與命令請(qǐng)求處理器進(jìn)行關(guān)聯(lián),使得客戶端可以向主服務(wù)器發(fā)送命令請(qǐng)求。

之后,客戶端向Redis服務(wù)器發(fā)送一個(gè)命令請(qǐng)求,那么客戶端套接字將產(chǎn)生 AE_READABLE事件,引發(fā)命令請(qǐng)求處理器執(zhí)行,處理器讀取客戶端的命令內(nèi)容, 然后傳給相關(guān)程序去執(zhí)行。

執(zhí)行命令將產(chǎn)生相應(yīng)的命令回復(fù),為了將這些命令回復(fù)傳送回客戶端,服務(wù)器會(huì)將客戶端套接字的AE_WRITABLE事件與命令回復(fù)處理器進(jìn)行關(guān)聯(lián): 當(dāng)客戶端嘗試讀取命令回復(fù)的時(shí)候,客戶端套接字將產(chǎn)生AE_WRITABLE事件, 觸發(fā)命令回復(fù)處理器執(zhí)行, 當(dāng)命令回復(fù)處理器將命令回復(fù)全部寫入到套接字之后, 服務(wù)器就會(huì)解除客戶端套接字的AE_WRITABLE事件與命令回復(fù)處理器之間的關(guān)聯(lián)。

Java技術(shù)干貨分享:徹底搞懂Redis的線程模型

 

Redis疑問快答

詳細(xì)的解答,請(qǐng)查看筆者之前的幾篇Redis博客。

是否使用過Redis集群,集群的原理是什么?

Redis Sentinal著眼于高可用,在master宕機(jī)時(shí)會(huì)自動(dòng)將slave提升為master,繼續(xù)提供服務(wù)。

Redis Cluster著眼于擴(kuò)展性,在單個(gè)redis內(nèi)存不足時(shí),使用Cluster進(jìn)行分片存儲(chǔ)。

如何使用過Redis做異步隊(duì)列?

一般使用list結(jié)構(gòu)作為隊(duì)列,rpush生產(chǎn)消息,lpop消費(fèi)消息。 當(dāng)lpop沒有消息的時(shí)候,要適當(dāng)sleep一會(huì)再重試。

如果不用sleep,list還有個(gè)指令叫blpop,在沒有消息的時(shí)候,它會(huì)阻塞住直到消息到來。

如果想要生產(chǎn)一次消費(fèi)多次,可以使用pub/sub主題訂閱者模式,可以實(shí)現(xiàn)1:N的消息隊(duì)列,但在消費(fèi)者下線后,生產(chǎn)的消息會(huì)丟失,想要持久化的話,需要使用消息隊(duì)列如rabbitmq等。

redis如何實(shí)現(xiàn)延時(shí)隊(duì)列?

使用sortedset,拿時(shí)間戳作為score,消息內(nèi)容作為key調(diào)用zadd來生產(chǎn)消息,消費(fèi)者用zrangebyscore指令獲取N秒之前的數(shù)據(jù)輪詢進(jìn)行處理。

如果有大量的key需要設(shè)置同一時(shí)間過期,需要注意什么?

如果大量的key過期時(shí)間設(shè)置的過于集中,到過期的那個(gè)時(shí)間點(diǎn),redis可能會(huì)出現(xiàn)短暫的卡頓現(xiàn)象。 一般需要在過期時(shí)間上加一個(gè)隨機(jī)值,使得過期時(shí)間分散一些。

Redis單點(diǎn)吞吐量

單點(diǎn)TPS達(dá)到8萬/秒,QPS達(dá)到10萬/秒,補(bǔ)充下TPS和QPS的概念

  1. QPS: 應(yīng)用系統(tǒng)每秒鐘最大能接受的用戶訪問量。每秒鐘處理完請(qǐng)求的次數(shù),注意這里是處理完,具體是指發(fā)出請(qǐng)求到服務(wù)器處理完成功返回結(jié)果。可以理解在server中有個(gè)counter,每處理一個(gè)請(qǐng)求加1,1秒后counter=QPS。
  2. TPS:每秒鐘最大能處理的請(qǐng)求數(shù)。每秒鐘處理完的事務(wù)次數(shù),一個(gè)應(yīng)用系統(tǒng)1s能完成多少事務(wù)處理,一個(gè)事務(wù)在分布式處理中,可能會(huì)對(duì)應(yīng)多個(gè)請(qǐng)求,對(duì)于衡量單個(gè)接口服務(wù)的處理能力,用QPS比較合理。

Redis哈希槽

Redis集群沒有使用一致性hash,而是引入了哈希槽的概念,當(dāng)需要在 Redis 集群中放置一個(gè) key-value 時(shí),根據(jù) CRC16(key) mod 16384的值,決定將一個(gè)key放到哪個(gè)桶中。

Redis集群最大節(jié)點(diǎn)個(gè)數(shù)是多少?

Redis集群預(yù)分好16384個(gè)桶(哈希槽)

Redis事務(wù)是什么?

Redis事務(wù)可以一次執(zhí)行多個(gè)命令,有以下特點(diǎn):

  • 批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存。
  • 收到 EXEC 命令后進(jìn)入事務(wù)執(zhí)行,事務(wù)中任意命令執(zhí)行失敗,其余的命令依然被執(zhí)行。
  • 在事務(wù)執(zhí)行過程,其他客戶端提交的命令請(qǐng)求不會(huì)插入到事務(wù)執(zhí)行命令序列中。

事務(wù)可以理解為一個(gè)打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會(huì)導(dǎo)致前面已做指令的回滾,也不會(huì)造成后續(xù)的指令不做。

分享到:
標(biāo)簽:線程 模型 Redis
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評(píng)定2018-06-03

通用課目體育訓(xùn)練成績評(píng)定