溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Redis單線(xiàn)程為什么這么快

發(fā)布時(shí)間:2022-01-15 16:19:21 來(lái)源:億速云 閱讀:121 作者:iii 欄目:大數(shù)據(jù)

本文小編為大家詳細(xì)介紹“Redis單線(xiàn)程為什么這么快”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Redis單線(xiàn)程為什么這么快”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

性能測(cè)試報(bào)告

查看了下阿里 Redis 的性能測(cè)試報(bào)告如下,能夠達(dá)到數(shù)十萬(wàn)、百萬(wàn)級(jí)別的 QPS(暫時(shí)忽略阿里對(duì) Redis 所做的優(yōu)化),我們從 Redis 的設(shè)計(jì)和實(shí)現(xiàn)來(lái)分析一下 Redis 是怎么做的。

Redis的設(shè)計(jì)與實(shí)現(xiàn)

其實(shí) Redis 主要是通過(guò)三個(gè)方面來(lái)滿(mǎn)足這樣高效吞吐量的性能需求

  • 高效的數(shù)據(jù)結(jié)構(gòu)

  • 多路復(fù)用 IO 模型

  • 事件機(jī)制

1、高效的數(shù)據(jù)結(jié)構(gòu)

Redis 支持的幾種高效的數(shù)據(jù)結(jié)構(gòu) string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)。

以上幾種對(duì)外暴露的數(shù)據(jù)結(jié)構(gòu)它們的底層編碼方式都是做了不同的優(yōu)化的,不細(xì)說(shuō)了,不是本文重點(diǎn)。

2、多路復(fù)用 IO 模型

假設(shè)某一時(shí)刻與 Redis 服務(wù)器建立了 1 萬(wàn)個(gè)長(zhǎng)連接,對(duì)于阻塞式 IO 的做法就是,對(duì)每一條連接都建立一個(gè)線(xiàn)程來(lái)處理,那么就需要 1萬(wàn)個(gè)線(xiàn)程,同時(shí)根據(jù)我們的經(jīng)驗(yàn)對(duì)于 IO 密集型的操作我們一般設(shè)置,線(xiàn)程數(shù) = 2 * CPU 數(shù)量 + 1,對(duì)于 CPU 密集型的操作一般設(shè)置線(xiàn)程 = CPU 數(shù)量 + 1。

當(dāng)然各種書(shū)籍或者網(wǎng)上也有一個(gè)詳細(xì)的計(jì)算公式可以算出更加合適準(zhǔn)確的線(xiàn)程數(shù)量,但是得到的結(jié)果往往是一個(gè)比較小的值,像阻塞式 IO 這也動(dòng)則創(chuàng)建成千上萬(wàn)的線(xiàn)程,系統(tǒng)是無(wú)法承載這樣的負(fù)荷的更加彈不上高效的吞吐量和服務(wù)了。

而多路復(fù)用 IO 模型的做法是,用一個(gè)線(xiàn)程將這一萬(wàn)個(gè)建立成功的鏈接陸續(xù)的放入 event_poll,event_poll 會(huì)為這一萬(wàn)個(gè)長(zhǎng)連接注冊(cè)回調(diào)函數(shù),當(dāng)某一個(gè)長(zhǎng)連接準(zhǔn)備就緒后(建立建立成功、數(shù)據(jù)讀取完成等),就會(huì)通過(guò)回調(diào)函數(shù)寫(xiě)入到 event_poll 的就緒隊(duì)列 rdlist 中,這樣這個(gè)單線(xiàn)程就可以通過(guò)讀取 rdlist 獲取到需要的數(shù)據(jù)。

需要注意的是,除了異步 IO 外,其它的 I/O 模型其實(shí)都可以歸類(lèi)為阻塞式 I/O 模型,不同的是像阻塞式 I/O 模型在第一階段讀取數(shù)據(jù)的時(shí)候,如果此時(shí)數(shù)據(jù)未準(zhǔn)備就緒需要阻塞,在第二階段數(shù)據(jù)準(zhǔn)備就緒后需要將數(shù)據(jù)從內(nèi)核態(tài)復(fù)制到用戶(hù)態(tài)這一步也是阻塞的。而多路復(fù)用 IO 模型在第一階段是不阻塞的,只會(huì)在第二階段阻塞。

通過(guò)這種方式,就可以用 1 個(gè)或者幾個(gè)線(xiàn)程來(lái)處理大量的連接了,極大的提升了吐吞量

3、事件機(jī)制

Redis 客戶(hù)端與 Redis 服務(wù)端建立連接,發(fā)送命令,Redis 服務(wù)器響應(yīng)命令都是需要通過(guò)事件機(jī)制來(lái)做的,如下圖

Redis單線(xiàn)程為什么這么快

  • 首先 redis 服務(wù)器運(yùn)行,監(jiān)聽(tīng)套接字的 AE_READABLE 事件處于監(jiān)聽(tīng)的狀態(tài)下,此時(shí)連接應(yīng)答處理器工作

  • 客戶(hù)端與 Redis 服務(wù)器發(fā)起建立連接,監(jiān)聽(tīng)套接字產(chǎn)生 AE_READABLE 事件,當(dāng) IO 多路復(fù)用程序監(jiān)聽(tīng)到其準(zhǔn)備就緒后,將該事件壓入隊(duì)列中,由文件事件分派器獲取隊(duì)列中的事件交于連接應(yīng)答處理器工作處理,應(yīng)答客戶(hù)端建立連接成功,同時(shí)將客戶(hù)端 socket 的 AE_READABLE 事件壓入隊(duì)列由文件事件分派器獲取隊(duì)列中的事件交命令請(qǐng)求處理器關(guān)聯(lián)

  • 客戶(hù)端發(fā)送 set key value 請(qǐng)求,客戶(hù)端 socket 的 AE_READABLE 事件,當(dāng) IO 多路復(fù)用程序監(jiān)聽(tīng)到其準(zhǔn)備就緒后,將該事件壓入隊(duì)列中,由文件事件分派器獲取隊(duì)列中的事件交于命令請(qǐng)求處理器關(guān)聯(lián)處理

  • 命令請(qǐng)求處理器關(guān)聯(lián)處理完成后,需要響應(yīng)客戶(hù)端操作完成,此時(shí)將產(chǎn)生 socket 的 AE_WRITEABLE 事件壓入隊(duì)列,由文件事件分派器獲取隊(duì)列中的事件交于命令恢復(fù)處理器處理,返回操作結(jié)果,完成后將解除 AE_WRITEABLE 事件與命令恢復(fù)處理器的關(guān)聯(lián)

reactor模式

大體上可以說(shuō) Redis 的工作模式是,reactor 模式配合一個(gè)隊(duì)列,用一個(gè) serverAccept 線(xiàn)程來(lái)處理建立請(qǐng)求的鏈接,并且通過(guò) IO 多路復(fù)用模型,讓內(nèi)核來(lái)監(jiān)聽(tīng)這些 socket,一旦某些 socket 的讀寫(xiě)事件準(zhǔn)備就緒后就對(duì)應(yīng)的事件壓入隊(duì)列中,然后 worker 工作,由文件事件分派器從中獲取事件交于對(duì)應(yīng)的處理器去執(zhí)行,當(dāng)某個(gè)事件執(zhí)行完成后文件事件分派器才會(huì)從隊(duì)列中獲取下一個(gè)事件進(jìn)行處理。

可以類(lèi)比在 netty 中,我們一般會(huì)設(shè)置 bossGroup 和 workerGroup 默認(rèn)情況下 bossGroup 為 1,workerGroup = 2 * cpu 數(shù)量,這樣可以由多個(gè)線(xiàn)程來(lái)處理讀寫(xiě)就緒的事件,但是其中不能有比較耗時(shí)的操作如果有的話(huà)需要將其放入線(xiàn)程池中,不然會(huì)降低其吐吞量。在 Redis 中我們可以看做這二者的值都是 1。

為什么說(shuō)存儲(chǔ)的值不宜過(guò)大

比如一個(gè) string key = a,存儲(chǔ)了 500MB,首先讀取事件壓入隊(duì)列中,文件事件分派器從中獲取到后,交于命令請(qǐng)求處理器處理,此處就涉及到從磁盤(pán)中加載 500MB。

比如是普通的 SSD 硬盤(pán),讀取速度 200MB/S,那么需要 2.5S 的讀取時(shí)間,在內(nèi)存中讀取數(shù)據(jù)比較快比如 DDR4 中 50G/秒,讀取 500MB 需要 100 毫秒左右。

線(xiàn)程的庫(kù)一般默認(rèn) 10 毫秒就算慢查詢(xún)了,大部分的指令執(zhí)行時(shí)間都是微秒級(jí)別,此時(shí)其它 socket 所有的請(qǐng)求都將處于等待過(guò)程中,就會(huì)導(dǎo)致阻塞了 100 毫秒,同時(shí)又會(huì)占用較大的帶寬導(dǎo)致吞吐量進(jìn)一步下降。

讀到這里,這篇“Redis單線(xiàn)程為什么這么快”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI