偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:為什么單線程的 Redis 可以實(shí)現(xiàn)高并發(fā)訪問

存儲(chǔ) 存儲(chǔ)軟件 Redis
從Redis自身特性來說,Redis是基于內(nèi)存的數(shù)據(jù)庫,所以數(shù)據(jù)處理速度非???。另外它的底層使用了很多效率很高的數(shù)據(jù)結(jié)構(gòu),如哈希表和跳表等。另外Redis從狹義上面來說他是單線程的,網(wǎng)絡(luò)請(qǐng)求解析與數(shù)據(jù)讀寫都是由主線程完成。

 [[442488]]

背景

上回說到小楓在接受面試官的拷打,所幸第一個(gè)問題回答的還不錯(cuò),因此面試官對(duì)于小楓的初步印象還行。我們接著來看看小楓是怎么和面試官繼續(xù)過招的吧,他還能扛得住面試官幾個(gè)連環(huán)炮呢?

面試官考察目的分析

面試官:Redis了解嗎?說說為什么單線程的Redis可以支持高并發(fā)訪問?

面試官考察目的分析:

1、考察候選同學(xué)對(duì)于Redis原理的理解程度;

2、考察候選同學(xué)對(duì)于網(wǎng)絡(luò)連接的理解程度;

面試題分析

面試官的問題中包含了兩個(gè)關(guān)鍵詞,一個(gè)是單線程一個(gè)是高并發(fā)訪問,因此我們?cè)诨卮饐栴}的時(shí)候主要從兩個(gè)方面出發(fā),先解釋清楚為什么Redis選擇單線程的實(shí)現(xiàn)方式,再解釋清楚為什么Redis能支持高并發(fā)訪問。

小楓:(內(nèi)心OS:根據(jù)面試官的問題,決定從兩方面來進(jìn)行闡述,先整理下回答思路)

從Redis自身特性來說,Redis是基于內(nèi)存的數(shù)據(jù)庫,所以數(shù)據(jù)處理速度非???。另外它的底層使用了很多效率很高的數(shù)據(jù)結(jié)構(gòu),如哈希表和跳表等。另外Redis從狹義上面來說他是單線程的,網(wǎng)絡(luò)請(qǐng)求解析與數(shù)據(jù)讀寫都是由主線程完成。因此它內(nèi)部就省去了很多多線程訪問共享數(shù)據(jù)資源的繁瑣設(shè)計(jì),同時(shí)也避免了頻繁的線程上下文切換因此減少了多線程的系統(tǒng)開銷。

從IO模型角度來說,Redis使用的是IO多路復(fù)用模型,使得它可以在網(wǎng)絡(luò)IO操作并發(fā)處理數(shù)十萬的客戶端網(wǎng)絡(luò)連接,實(shí)現(xiàn)非常高的網(wǎng)絡(luò)吞吐率。這也是Redis可以實(shí)現(xiàn)高并發(fā)訪問的最主要的原因。

PS:關(guān)于IO模型可以參考以前的文章

一文說清BIO、NIO、AIO不同IO模型演進(jìn)之路

面試官:剛才你提到了IO多路復(fù)用模型,能詳細(xì)說下Redis的IO多路復(fù)用的原理嗎?

小楓:(內(nèi)心OS:當(dāng)時(shí)為了搞清楚這個(gè)問題,還特意扒了Redis源碼來看,對(duì)于一個(gè)Java程序猿來說,看c真的頭暈啊)

好的。首先要明確的是Redis依賴Linux操作系統(tǒng)實(shí)現(xiàn)的高性能IO,剛剛提到的多路復(fù)用IO模型實(shí)際也是傳統(tǒng)阻塞型IO模型演化而來的。在傳統(tǒng)的網(wǎng)絡(luò)IO操作中,accept() 和 recv()函數(shù)都是阻塞型的,一旦發(fā)生阻塞,影響其他網(wǎng)絡(luò)連接。但是在多路復(fù)用IO模型中,可以實(shí)現(xiàn)同時(shí)存在多個(gè)socket,內(nèi)核監(jiān)聽socket中的是否有數(shù)據(jù)請(qǐng)求或者連接請(qǐng)求,如果有請(qǐng)求,那么內(nèi)核就會(huì)交給Redis進(jìn)行處理,因此Redis的主線程,也就是單線程的Redis可以處理多個(gè)IO連接。

整個(gè)過程涉及到epoll_create、epoll_ctl以及epoll_wait三個(gè)系統(tǒng)調(diào)用,具體的過程大致是這樣的:

1、當(dāng)Redis啟動(dòng)的時(shí)候,會(huì)調(diào)用內(nèi)核的epoll_create創(chuàng)建epoll對(duì)象,在這個(gè)過程中包含初始化紅黑樹cache以及雙向鏈表,紅黑樹中主要存儲(chǔ)了需要進(jìn)行狀態(tài)監(jiān)控的FD,實(shí)際就是epitem結(jié)構(gòu)體,雙向鏈表中存儲(chǔ)了需要返回給用戶已經(jīng)處于就緒狀態(tài)的事件。

2、調(diào)用epoll_ctl(),通過epoll_ctl注冊(cè)要監(jiān)聽的事件類型,將客戶端FD以及需要監(jiān)聽的事件添加到紅黑樹cache中,添加時(shí)進(jìn)行檢查,如果已存在則返回,如果不存在則添加到節(jié)點(diǎn)當(dāng)中,同時(shí)注冊(cè)相應(yīng)的事件回調(diào)函數(shù),如果存在連接事件或者讀寫事件,那么就會(huì)通過回調(diào)函數(shù)將就緒的事件加入到雙向鏈表中,實(shí)際就是紅黑樹的節(jié)點(diǎn)。

3、Redis調(diào)用epoll_wait獲取已經(jīng)就緒的事件的fired數(shù)組,fire數(shù)組的事件中存儲(chǔ)了就緒的FD以及事件類型,遍歷數(shù)組中的事件,根據(jù)事件類型處理函數(shù)繼續(xù)后續(xù)的處理。如果是讀事件那就調(diào)用讀事件處理函數(shù)進(jìn)行處理。對(duì)于Redis來說它只要關(guān)注鏈表中有沒有數(shù)據(jù)就好,有數(shù)據(jù)就會(huì)進(jìn)行讀取,沒有數(shù)據(jù)則阻塞超過timeout之后再進(jìn)行調(diào)用。在大多數(shù)情況下,返回的數(shù)組中包含的事件并不多。通過這樣的設(shè)計(jì),Redis不需要一直輪訓(xùn)檢查到底有沒有實(shí)際的請(qǐng)求發(fā)生,避免了CPU資源的浪費(fèi)。因此及時(shí)是單線程的Redis,借助于epoll機(jī)制,它也可以實(shí)現(xiàn)數(shù)十萬連接的并發(fā)處理。

面試官:(內(nèi)心OS:小伙子回答的不錯(cuò),看來常見的面試題難不倒你啊,那么我就來問問陷阱題吧,嘿嘿)

總結(jié)

程序猿小楓這次表現(xiàn)不錯(cuò),抗住了面試官關(guān)于Redis的連環(huán)炮,那么接下來的問題他還能回答出來嗎?請(qǐng)大家繼續(xù)拭目以待哦。

本文轉(zhuǎn)載自微信公眾號(hào)「慕楓技術(shù)筆記」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系慕楓技術(shù)筆記公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 慕楓技術(shù)筆記
相關(guān)推薦

2020-10-30 16:20:38

Redis單線程高并發(fā)

2019-05-07 09:44:45

Redis高并發(fā)模型

2019-05-06 11:12:18

Redis高并發(fā)單線程

2022-07-18 13:59:43

Redis單線程進(jìn)程

2023-03-21 08:02:36

Redis6.0IO多線程

2021-08-10 07:00:01

Redis單線程并發(fā)

2023-10-15 12:23:10

單線程Redis

2019-04-02 11:20:48

Redis高并發(fā)單線程

2020-06-11 09:35:39

Redis單線程Java

2019-06-17 14:20:51

Redis數(shù)據(jù)庫Java

2023-08-17 14:12:17

2022-07-06 13:48:24

RedisSentinel機(jī)制

2019-11-25 10:13:52

Redis單線程I

2025-09-24 17:05:02

2023-12-20 14:35:37

Java虛擬線程

2019-02-18 08:10:53

2021-08-05 12:41:57

高并發(fā)性能CAS

2020-11-17 10:20:53

Redis多線程單線程

2025-06-17 00:22:00

2021-03-03 08:01:58

Redis多線程程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)