濮阳杆衣贸易有限公司

主頁 > 知識庫 > Redis憑啥可以這么快

Redis憑啥可以這么快

熱門標(biāo)簽:魔獸2青云地圖標(biāo)注 貴州電銷卡外呼系統(tǒng) 北京400電話辦理收費(fèi)標(biāo)準(zhǔn) 鄭州人工智能電銷機(jī)器人系統(tǒng) 十堰營銷電銷機(jī)器人哪家便宜 日本中國地圖標(biāo)注 山東外呼銷售系統(tǒng)招商 超呼電話機(jī)器人 宿遷便宜外呼系統(tǒng)平臺

在日常開發(fā)中,為了保證數(shù)據(jù)的一致性,我們一般都選擇關(guān)系型數(shù)據(jù)庫來存儲數(shù)據(jù),如 MySQL,Oracle 等,因?yàn)殛P(guān)系型數(shù)據(jù)庫有著事務(wù)的特性。然而在并發(fā)量比較大的業(yè)務(wù)場景,關(guān)系型數(shù)據(jù)庫卻又往往會成為系統(tǒng)瓶頸,無法完全滿足我們的需求,所以就需要使用到緩存,而非關(guān)系型數(shù)據(jù)庫,即 NoSQL 數(shù)據(jù)庫往往又會成為最佳選擇。

NoSQL 數(shù)據(jù)庫最常見的解釋是 non-relational,也有人解釋為 Not Only SQL。非關(guān)系型數(shù)據(jù)庫不保證事務(wù),也就是不具備事務(wù) ACID 特性,這也是非關(guān)系型數(shù)據(jù)庫和關(guān)系型數(shù)據(jù)庫最大的區(qū)別,而我們即將介紹的 Redis 就屬于 NoSQL 數(shù)據(jù)庫的一種。

什么是 Redis

Redis 全稱是:REmote DIctionary Service,即遠(yuǎn)程字典服務(wù)。Redis 是一個開源的(遵守 BSD 協(xié)議)、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value 數(shù)據(jù)庫。

Redis 具有以下特性:

1、支持豐富的數(shù)據(jù)類型:字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets),位圖等。
2、功能豐富:提供了持久化機(jī)制,過期策略,訂閱/發(fā)布等功能。
3、高性能,高可用且支持集群。
4、提供了多種語言的 API。

Redis 的安裝

1、下載對應(yīng)版本的安裝包,如:Redis 5.0.5 版本,其他版本也可以點(diǎn)擊這里進(jìn)行下載。

2、下載好之后傳到服務(wù)器指定目錄,執(zhí)行命令 tar -zxvf redis-5.0.5.tar.gz 進(jìn)行解壓。

3、解壓成功之后,進(jìn)入 Redis 主目錄,執(zhí)行命令 make make install PREFIX=/xxx/xxx/redis-5.0.5 進(jìn)行安裝,如果不指定目錄,則默認(rèn)是安裝在 /usr/local 目錄下。

4、安裝成功之后可以看到 Redis 主目錄下多了一個 bin 目錄,bin 目錄內(nèi)包含了一些可執(zhí)行腳本。

5、回到 Redis 主目錄下,找到 redis.conf 配置文件,將其中的配置 daemonize no 修改為 daemonize yes,表示在后臺啟動服務(wù)。

6、然后就可以執(zhí)行命令 /xxx/xxx/redis-5.0.5/bin/redis-server /xxx/xxx/redis-5.0.5/redis.conf 啟動 Redis 服務(wù)。 Redis 到底有多快

大家可能都知道 Redis 很快,可是 Redis 到底能有多快呢,比如 Redis 的吞吐量能達(dá)到多少?我想這就不是每一個人都能說的上來一個具體的數(shù)字了。

Redis 官方提供了一個測試腳本,可以供我們測試 Redis 的 吞吐量。

redis-benchmark -q -n 100000 可以測試常用命令的吞吐量。 redis-benchmark -t set,lpush -n 100000 -q 測試 Redis 處理 setlpush 命令的吞吐量。 redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')" 測試 Redis 處理 Lua 腳本等吞吐量。

下圖就是我這邊執(zhí)行第一條命令的自測結(jié)果,可以看到大部分命令的吞吐量都可以達(dá)到 4 萬以上,也就是說每秒鐘可以處理 4 萬次以上請求:

但是如果你以為這就是 Redis 的真實(shí)吞吐量,那就錯了。實(shí)際上,Redis 官方的測試結(jié)果是可以達(dá)到 10 萬的吞吐量,下圖就是官方提供的一個基準(zhǔn)測試結(jié)果(縱坐標(biāo)就是吞吐量,橫坐標(biāo)是連接數(shù)):

Redis 是單線程還是多線程

這個問題比較經(jīng)典,因?yàn)樵诤芏嗳说恼J(rèn)知里,Redis 就是單線程的。然而 Redis4.0 版本開始就有了多線程的概念,雖然處理命令請求的核心模塊確實(shí)是保證了單線程執(zhí)行,然而在其他許多地方已經(jīng)有了多線程,比如:在后臺刪除對象,通過 Redis 模塊實(shí)現(xiàn)阻塞命令,生成 dump 文件,以及 6.0 版本中網(wǎng)絡(luò) I/O 實(shí)現(xiàn)了多線程等,而且在未來 Redis 應(yīng)該會有越來越多的模塊實(shí)現(xiàn)多線程。

所謂的單線程,只是說 Redis 的處理客戶端的請求(即執(zhí)行命令)時,是單線程去執(zhí)行的,并不是說整個 Redis 都是單線程。

Redis 為什么選擇使用單線程來執(zhí)行請求

Redis 為什么會選擇使用單線程呢?這是因?yàn)?CPU 成為 Redis 瓶頸的情況并不常見,成為 Redis 瓶頸的通常是內(nèi)存或網(wǎng)絡(luò)帶寬。例如,在一個普通的 Linux 系統(tǒng)上使用 pipelining 命令,Redis 可以每秒完成 100 萬個請求,所以如果我們的應(yīng)用程序主要使用 O(N)O(log(N)) 復(fù)雜度的命令,它幾乎不會使用太多的 CPU。

那么既然 CPU 不會成為瓶頸,理所當(dāng)然的就沒必要去使用多線程來執(zhí)行命令,我們需要明確的一個問題就是多線程一定比單線程快嗎?答案是不一定。因?yàn)槎嗑€程也是有代價的,最直接的兩個代價就是線程的創(chuàng)建和銷毀線程(當(dāng)然可以通過線程池來一定程度的減少頻繁的創(chuàng)建線程和銷毀線程)以及線程的上下文切換。

在我們的日常系統(tǒng)中,主要可以區(qū)分為兩種:CPU 密集型 和 IO 密集型。

CPU 密集型:

這種系統(tǒng)就說明 CPU 的利用率很高,那么使用多線程反而會增加上下文切換而帶來額外的開銷,所以使用多線程效率可能會不升反降。舉個例子:假如你現(xiàn)在在干活,你一直不停的在做一件事,需要 1 分鐘可以做完,但是你中途總是被人打斷,需要花 1 秒鐘時間步行到旁邊去做另一件事,假如這件事也需要 1 分鐘,那么你因?yàn)榉磸?fù)切換做兩件事,每切換一次就要花 1 秒鐘,最后做完這 2 件事的時間肯定大于 2 分鐘(取決于中途切換的次數(shù)),但是如果中途不被打斷,你做完一件事再去做另一件事,那么你最多只需要切換 1 次,也就是 21 秒就能做完。

 IO 密集型:

IO 操作也可以分為磁盤 IO 和網(wǎng)絡(luò) IO 等操作。大部分 IO 操作的特點(diǎn)是比較耗時且 CPU 利用率不高,所以 Redis 6.0 版本網(wǎng)絡(luò) IO 會改進(jìn)為多線程。至于磁盤 IO,因?yàn)?Redis 中的數(shù)據(jù)都存儲在內(nèi)存(也可以持久化),所以并不會過多的涉及到磁盤操作。舉個例子:假如你現(xiàn)在給樹苗澆水,你每澆完一次水之后就需要等別人給你加水之后你才能繼續(xù)澆,那么假如這個等待過程需要 5 秒鐘,也就是說你澆完一次水就可以休息 5 秒鐘,而你切換去做另一件事來回只需要 2 秒,那么你完全可以先去做另一件事,做完之后再回來,這樣就可以充分利用你空閑的 5 秒鐘時間,從而提升了效率。

使用多線程還會帶來一個問題就是數(shù)據(jù)的安全性,所以多線程編程都會涉及到鎖競爭,由此也會帶來額外的開銷。

什么是 I/O 多路復(fù)用

I/O 指的是網(wǎng)絡(luò) I/O, 多路指的是多個 TCP 連接(如 Socket),復(fù)用指的是復(fù)用一個或多個線程。I/O 多路復(fù)用的核心原理就是不再由應(yīng)用程序自己來監(jiān)聽連接,而是由服務(wù)器內(nèi)核替應(yīng)用程序監(jiān)聽。

Redis 中,其多路復(fù)用有多種實(shí)現(xiàn),如:select,epoll,evport,kqueue 等。

我們用去餐廳吃飯為的例子來解釋一下 I/O 多路復(fù)用機(jī)制(點(diǎn)餐人相當(dāng)于客戶端,餐廳的廚房相當(dāng)于服務(wù)器,廚師就是線程)。

阻塞 IO:張三去餐廳吃飯,點(diǎn)了一道菜,這時候他啥事也不干了,就是一直等,等到廚師炒好菜,他就把菜端走開始吃飯了。也就是在菜被炒好之前,張三被阻塞了,這就是 BIO(阻塞 IO),效率會非常低下。

非阻塞 IO:張三去餐廳吃飯,點(diǎn)了一道菜,這時候張三他不會一直等,找了個位置坐下,刷刷抖音,打打電話,做點(diǎn)其他事,然后每隔一段時間就去廚房問一下自己的菜好了沒有。這種就屬于非阻塞 IO,這種方式雖然可以提高性能,但是如果有大量 IO 都來定期輪詢,也會給服務(wù)器造成非常大的負(fù)擔(dān)。

事件驅(qū)動機(jī)制:張三去餐廳吃飯,點(diǎn)了一道菜,這時候他找了個位置坐下來等: 廚房那邊菜做好了就會把菜端出來了,但是并不知道這道菜是誰的,于是就挨個詢問顧客,這就是多路復(fù)用中的 select 模型,不過 select 模型最多只能監(jiān)聽 1024socketpoll 模型解決了這個限制問題)。廚房做好了菜直接把菜放在窗口上,大喊一聲,某某菜做好了,是誰的快過來拿,這時候聽到通知的人就會自己去拿,這就是多路復(fù)用中的 epoll 模型。

需要注意的是在 IO 多路復(fù)用機(jī)制下,客戶端可以阻塞也可以選擇不阻塞(大部分場景下是阻塞 IO),這個要具體情況具體分析,但是在多路復(fù)用機(jī)制下,服務(wù)端就可以通過多線程(上面示例中可以多幾個廚師同時炒菜)來提升并發(fā)效率。

Redis 中 I/O 多路復(fù)用的應(yīng)用

Redis 服務(wù)器是一個事件驅(qū)動程序,服務(wù)器需要處理兩類事件:文件事件和時間事件。

文件事件:Redis 服務(wù)器和客戶端(或其他服務(wù)器)進(jìn)行通信會產(chǎn)生相應(yīng)的文件事件,然后服務(wù)器通過監(jiān)聽并處理這些事件來完成一系列的通信操作。

時間事件:Redis 內(nèi)部的一些在給定時間之內(nèi)需要進(jìn)行的操作。

Redis 的文件事件處理器以單線程的方式運(yùn)行,其內(nèi)部使用了 I/O 多路復(fù)用程序來同時監(jiān)聽多個套接字(Socket)連接,提升了性能的同時又保持了內(nèi)部單線程設(shè)計(jì)的簡單性。下圖就是文件事件處理器的示意圖:

I/O 多路復(fù)用程序雖然會同時監(jiān)聽多個 Socket 連接,但是其會將監(jiān)聽的 Socket 都放到一個隊(duì)列里面,然后通過這個隊(duì)列有序的,同步的將每個 Socket 對應(yīng)的事件傳送給文件事件分派器,再由文件事件分派器分派給對應(yīng)的事件處理器進(jìn)行處理,只有當(dāng)一個 Socket 所對應(yīng)的事件被處理完畢之后,I/O多路復(fù)用程序才會繼續(xù)向文件事件分派器傳送下一個 Socket 所對應(yīng)的事件,這也可以驗(yàn)證上面的結(jié)論,處理客戶端的命令請求是單線程的方式逐個處理,但是事件處理器內(nèi)并不是只有一個線程。

Redis 為什么這么快

Redis 為什么這么快的原因前面已經(jīng)基本提到了,現(xiàn)在我們再進(jìn)行總結(jié)一下:

1、Redis 是一款純內(nèi)存結(jié)構(gòu),避免了磁盤 I/O 等耗時操作。

2、Redis 命令處理的核心模塊為單線程,減少了鎖競爭,以及頻繁創(chuàng)建線程和銷毀線程的代價,減少了線程上下文切換的消耗。

3、采用了 I/O 多路復(fù)用機(jī)制,大大提升了并發(fā)效率。

到此這篇關(guān)于Redis憑啥可以這么快的文章就介紹到這了,更多相關(guān)Redis為什么快內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Redis不是一直號稱單線程效率也很高嗎,為什么又采用多線程了?
  • redis單線程快的原因和原理
  • Redis為什么快如何實(shí)現(xiàn)高可用及持久化
  • 為啥Redis使用pipelining會更快
  • Redis高效率原因及數(shù)據(jù)結(jié)構(gòu)分析

標(biāo)簽:果洛 楊凌 大慶 吉安 朝陽 臺州 北京 江蘇

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Redis憑啥可以這么快》,本文關(guān)鍵詞  Redis,憑啥,可以,這么,快,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Redis憑啥可以這么快》相關(guān)的同類信息!
  • 本頁收集關(guān)于Redis憑啥可以這么快的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    马关县| 云梦县| 绍兴市| 荥经县| 黎平县| 仲巴县| 兴国县| 陇南市| 扶风县| 宁阳县| 峨眉山市| 宁明县| 江西省| 同德县| 南平市| 武安市| 休宁县| 大埔县| 江山市| 托克逊县| 永川市| 固原市| 兰坪| 锡林浩特市| 亚东县| 江川县| 泸溪县| 许昌县| 开封市| 盖州市| 双城市| 张家港市| 高碑店市| 柳河县| 仁布县| 余庆县| 普陀区| 宁河县| 烟台市| 塔城市| 闽侯县|