為什么說Redis是單線程的枯跑?

近乎所有與Java相關的面試都會問到緩存的問題,基礎一點的會問到什么是“二八定律”白热、什么是“熱數(shù)據(jù)和冷數(shù)據(jù)” 敛助,復雜一點的會問到緩存雪崩、緩存穿透屋确、緩存預熱纳击、緩存更新、緩存降級等問題攻臀,這些看似不常見的概念焕数,都與我們的緩存服務器相關,一般常用的緩存服務器有Redis刨啸、Memcached等堡赔,而筆者目前最常用的也只有Redis這一種。

如果你在以前面試的時候還沒有遇到過面試官問你:為什么說Redis是單線程或者Redis為什么這么快设联?善已,那么你看到這篇文章的時候灼捂,你應該覺得是一件很幸運的事情!如果你剛好是一位高逼格的面試官换团,你也可以拿這道題去面試對面“望穿秋水”般的小伙伴悉稠,測試一下他的掌握程度。

好啦艘包!步入正題的猛!我們先探討一下Redis是什么,Redis為什么這么快想虎、然后在探討一下為什么Redis是單線程的秉溉?

?

? ? 一窿侈、Redis簡介


Redis是一個開源的內(nèi)存中的數(shù)據(jù)結構存儲系統(tǒng)季眷,它可以用作:數(shù)據(jù)庫墓猎、緩存和消息中間件胡诗。

它支持多種類型的數(shù)據(jù)結構邓线,如字符串(Strings)、散列(Hash)煌恢、列表(List)骇陈、集合(Set)、有序集合(Sorted Set或者是ZSet)與范圍查詢瑰抵,Bitmaps你雌,Hyperloglogs 和地理空間(Geospatial)索引半徑查詢。其中常見的數(shù)據(jù)結構類型有:String二汛、List婿崭、Set、Hash肴颊、ZSet這5種氓栈。

Redis 內(nèi)置了復制(Replication)、LUA腳本(Lua scripting)婿着、 LRU驅(qū)動事件(LRU eviction)授瘦、事務(Transactions) 和不同級別的磁盤持久化(Persistence),并通過 Redis哨兵(Sentinel)和自動分區(qū)(Cluster)提供高可用性(High Availability)竟宋。

Redis也提供了持久化的選項提完,這些選項可以讓用戶將自己的數(shù)據(jù)保存到磁盤上面進行存儲。根據(jù)實際情況丘侠,可以每隔一定時間將數(shù)據(jù)集導出到磁盤(快照)徒欣,或者追加到命令日志中(AOF只追加文件),他會在執(zhí)行寫命令時蜗字,將被執(zhí)行的寫命令復制到硬盤里面打肝。您也可以關閉持久化功能官研,將Redis作為一個高效的網(wǎng)絡的緩存數(shù)據(jù)功能使用。

Redis不使用表闯睹,他的數(shù)據(jù)庫不會預定義或者強制去要求用戶對Redis存儲的不同數(shù)據(jù)進行關聯(lián)戏羽。

數(shù)據(jù)庫的工作模式按存儲方式可分為:硬盤數(shù)據(jù)庫和內(nèi)存數(shù)據(jù)庫。Redis 將數(shù)據(jù)儲存在內(nèi)存里面楼吃,讀寫數(shù)據(jù)的時候都不會受到硬盤 I/O 速度的限制始花,所以速度極快。

1孩锡、硬盤數(shù)據(jù)庫的工作模式:?

2酷宵、內(nèi)存數(shù)據(jù)庫的工作模式:

看完上述的描述,對于一些常見的Redis相關的面試題躬窜,是否有所認識了浇垦,例如:什么是Redis、Redis常見的數(shù)據(jù)結構類型有哪些荣挨、Redis是如何進行持久化的等男韧。


? ? 二、Redis到底有多快


Redis采用的是基于內(nèi)存的采用的是單進程單線程模型的KV 數(shù)據(jù)庫默垄,由C語言編寫此虑,官方提供的數(shù)據(jù)是可以達到100000+的QPS(每秒內(nèi)查詢次數(shù))。這個數(shù)據(jù)不比采用單進程多線程的同樣基于內(nèi)存的 KV 數(shù)據(jù)庫 Memcached 差口锭!有興趣的可以參考官方的基準程序測試:https://redis.io/topics/benchmarks

橫軸是連接數(shù)朦前,縱軸是QPS。此時鹃操,這張圖反映了一個數(shù)量級韭寸,希望大家在面試的時候可以正確的描述出來,不要問你的時候荆隘,你回答的數(shù)量級相差甚遠恩伺!


? ? 三、Redis為什么這么快


1臭胜、完全基于內(nèi)存莫其,絕大部分請求是純粹的內(nèi)存操作,非乘嗜快速乱陡。數(shù)據(jù)存在內(nèi)存中,類似于HashMap仪壮,HashMap的優(yōu)勢就是查找和操作的時間復雜度都是O(1)憨颠;

2、數(shù)據(jù)結構簡單,對數(shù)據(jù)操作也簡單爽彤,Redis中的數(shù)據(jù)結構是專門進行設計的养盗;

3、采用單線程适篙,避免了不必要的上下文切換和競爭條件往核,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題嚷节,不存在加鎖釋放鎖操作聂儒,沒有因為可能出現(xiàn)死鎖而導致的性能消耗;

4硫痰、使用多路I/O復用模型衩婚,非阻塞IO;

5效斑、使用底層模型不同非春,它們之間底層實現(xiàn)方式以及與客戶端之間通信的應用協(xié)議不一樣,Redis直接自己構建了VM 機制 缓屠,因為一般的系統(tǒng)調(diào)用系統(tǒng)函數(shù)的話奇昙,會浪費一定的時間去移動和請求;

以上幾點都比較好理解藏研,下邊我們針對多路 I/O 復用模型進行簡單的探討:

多路I/O復用模型是利用 select敬矩、poll概行、epoll 可以同時監(jiān)察多個流的 I/O 事件的能力蠢挡,在空閑的時候,會把當前線程阻塞掉凳忙,當有一個或多個流有 I/O 事件時业踏,就從阻塞態(tài)中喚醒,于是程序就會輪詢一遍所有的流(epoll 是只輪詢那些真正發(fā)出了事件的流)涧卵,并且只依次順序的處理就緒的流勤家,這種做法就避免了大量的無用操作。

這里“多路”指的是多個網(wǎng)絡連接柳恐,“復用”指的是復用同一個線程伐脖。采用多路 I/O 復用技術可以讓單個線程高效的處理多個連接請求(盡量減少網(wǎng)絡 IO 的時間消耗),且 Redis 在內(nèi)存中操作數(shù)據(jù)的速度非忱稚瑁快讼庇,也就是說內(nèi)存內(nèi)的操作不會成為影響Redis性能的瓶頸,主要由以上幾點造就了 Redis 具有很高的吞吐量近尚。

除了這些蠕啄,針對當前互聯(lián)網(wǎng)公司的技術需求以及結合主流技術,我自己整理了一套系統(tǒng)的架構技術體系,當你技術過硬的時候歼跟,能夠解決技術問題才會服眾和媳。不少公司都很重視高并發(fā)高可用的技術,特別是一線互聯(lián)網(wǎng)公司哈街,分布式留瞳、JVM、spring源碼分析骚秦、微服務等知識點已是面試的必考題撼港,這些東西可能你們平時在工作中接觸過,但是缺少的全面系統(tǒng)的學習骤竹,加入后端開發(fā)群:943918498帝牡,或是關注微信公眾號:Java資訊庫,回復“架構”蒙揣,免費領取架構資料靶溜。


? ? 四、那么為什么Redis是單線程的


我們首先要明白懒震,上邊的種種分析罩息,都是為了營造一個Redis很快的氛圍!官方FAQ表示个扰,因為Redis是基于內(nèi)存的操作瓷炮,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內(nèi)存的大小或者網(wǎng)絡帶寬递宅。既然單線程容易實現(xiàn)娘香,而且CPU不會成為瓶頸,那就順理成章地采用單線程的方案了(畢竟采用多線程會有很多麻煩0炝洹)烘绽。

可以參考:https://redis.io/topics/faq

看到這里,你可能會氣哭俐填!本以為會有什么重大的技術要點才使得Redis使用單線程就可以這么快安接,沒想到就是一句官方看似糊弄我們的回答!但是英融,我們已經(jīng)可以很清楚的解釋了為什么Redis這么快盏檐,并且正是由于在單線程模式的情況下已經(jīng)很快了,就沒有必要在使用多線程了驶悟!

但是胡野,我們使用單線程的方式是無法發(fā)揮多核CPU 性能,不過我們可以通過在單機開多個Redis 實例來完善撩银!

警告1:這里我們一直在強調(diào)的單線程给涕,只是在處理我們的網(wǎng)絡請求的時候只有一個線程來處理,一個正式的Redis Server運行的時候肯定是不止一個線程的,這里需要大家明確的注意一下够庙!例如Redis進行持久化的時候會以子進程或者子線程的方式執(zhí)行(具體是子線程還是子進程待讀者深入研究)恭应;例如我在測試服武器上查看Redis進程,然后找到該進程下的線程:

ps命令的“-T”參數(shù)表示顯示線程(Show threads, possibly with SPID column.)“SID”欄表示線程ID耘眨,而“CMD”欄則顯示了線程名稱昼榛。

警告2:在上圖中FAQ中的最后一段,表述了從Redis 4.0版本開始會支持多線程的方式剔难,但是胆屿,只是在某一些操作上進行多線程的操作!所以該篇文章在以后的版本中是否還是單線程的方式需要讀者考證偶宫!


? ? 五非迹、擴展


以下也是你應該知道的幾種模型,祝你的面試一臂之力纯趋!

1憎兽、單進程多線程模型:MySQL、Memcached吵冒、Oracle(Windows版本)纯命;

2、多進程模型:Oracle(Linux版本)痹栖;

3亿汞、Nginx有兩類進程,一類稱為Master進程(相當于管理進程)揪阿,另一類稱為Worker進程(實際工作進程)疗我。啟動方式有兩種:

(1)單進程啟動:此時系統(tǒng)中僅有一個進程,該進程既充當Master進程的角色图甜,也充當Worker進程的角色碍粥。

(2)多進程啟動:此時系統(tǒng)有且僅有一個Master進程,至少有一個Worker進程工作黑毅。

(3)Master進程主要進行一些全局性的初始化工作和管理Worker的工作;事件處理是在Worker中進行的钦讳。

? ? 原文出處:https://segmentfault.com/a/1190000017121908

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矿瘦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子愿卒,更是在濱河造成了極大的恐慌缚去,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琼开,死亡現(xiàn)場離奇詭異易结,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門搞动,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躏精,“玉大人,你說我怎么就攤上這事鹦肿〈V颍” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵箩溃,是天一觀的道長瞭吃。 經(jīng)常有香客問我,道長涣旨,這世上最難降的妖魔是什么歪架? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮霹陡,結果婚禮上牡拇,老公的妹妹穿的比我還像新娘。我一直安慰自己穆律,他們只是感情好惠呼,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峦耘,像睡著了一般剔蹋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辅髓,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天泣崩,我揣著相機與錄音,去河邊找鬼洛口。 笑死矫付,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的第焰。 我是一名探鬼主播买优,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挺举!你這毒婦竟也來了杀赢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤湘纵,失蹤者是張志新(化名)和其女友劉穎脂崔,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梧喷,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡砌左,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年脖咐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汇歹。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡屁擅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秤朗,到底是詐尸還是另有隱情煤蹭,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布取视,位于F島的核電站硝皂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏作谭。R本人自食惡果不足惜稽物,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望折欠。 院中可真熱鬧贝或,春花似錦、人聲如沸锐秦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酱床。三九已至羊赵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扇谣,已是汗流浹背昧捷。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留罐寨,地道東北人靡挥。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像鸯绿,于是被迫代替她去往敵國和親跋破。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Java繼承關系初始化順序 父類的靜態(tài)變量-->父類的靜態(tài)代碼塊-->子類的靜態(tài)變量-->子類的靜態(tài)代碼快-->父...
    第六象限閱讀 2,157評論 0 9
  • 一. 操作系統(tǒng)概念 操作系統(tǒng)位于底層硬件與應用軟件之間的一層.工作方式: 向下管理硬件,向上提供接口.操作系統(tǒng)進行...
    月亮是我踢彎得閱讀 5,967評論 3 28
  • 關于Mongodb的全面總結 MongoDB的內(nèi)部構造《MongoDB The Definitive Guide》...
    中v中閱讀 31,931評論 2 89
  • 假如你去超市買東西楞慈,但店員的漫不經(jīng)心激怒了你幔烛,你再也不想去這家超市買東西了,反正走遠一點也有囊蓝,或者干脆網(wǎng)上購買。第...
    kafkaliu閱讀 221評論 0 1
  • 又是一個鬧死人的晚上蝎宇,到處都是人弟劲,烏央烏央,無窮無盡姥芥。 我站在園子里兔乞,這是一處林間空地,周圍環(huán)繞著高高低低的樹木凉唐,...
    去看更遠的海閱讀 287評論 0 3