這篇文章將為大家詳細講解有關(guān)redis中關(guān)于分布式緩存的面試題有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)是專業(yè)的儋州網(wǎng)站建設(shè)公司,儋州接單;提供做網(wǎng)站、成都做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行儋州網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
redis 和 memcached 有什么區(qū)別?redis 的線程模型是什么?為什么 redis 單線程卻能支撐高并發(fā)?
面試官心理分析
這個是問 redis 的時候,最基本的問題吧,redis 最基本的一個內(nèi)部原理和特點,就是 redis 實際上是個單線程工作模型,你要是這個都不知道,那后面玩兒 redis 的時候,出了問題豈不是什么都不知道?
還有可能面試官會問問你 redis 和 memcached 的區(qū)別,但是 memcached 是早些年各大互聯(lián)網(wǎng)公司常用的緩存方案,但是現(xiàn)在近幾年基本都是 redis,沒什么公司用 memcached 了。
面試題剖析
redis 和 memcached 有啥區(qū)別?
redis 支持復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
redis 相比 memcached 來說,擁有更多的數(shù)據(jù)結(jié)構(gòu),能支持更豐富的數(shù)據(jù)操作。如果需要緩存能夠支持更復(fù)雜的結(jié)構(gòu)和操作, redis 會是不錯的選擇。
redis 原生支持集群模式
在 redis3.x 版本中,便能支持 cluster 模式,而 memcached 沒有原生的集群模式,需要依靠客戶端來實現(xiàn)往集群中分片寫入數(shù)據(jù)。
性能對比
由于 redis 只使用單核,而 memcached 可以使用多核,所以平均每一個核上 redis 在存儲小數(shù)據(jù)時比 memcached 性能更高。而在 100k 以上的數(shù)據(jù)中,memcached 性能要高于 redis。雖然 redis 最近也在存儲大數(shù)據(jù)的性能上進行優(yōu)化,但是比起 memcached,還是稍有遜色。
redis 的線程模型
redis 內(nèi)部使用文件事件處理器 file event handler
,這個文件事件處理器是單線程的,所以 redis 才叫做單線程的模型。它采用 IO 多路復(fù)用機制同時監(jiān)聽多個 socket,將產(chǎn)生事件的 socket 壓入內(nèi)存隊列中,事件分派器根據(jù) socket 上的事件類型來選擇對應(yīng)的事件處理器進行處理。
文件事件處理器的結(jié)構(gòu)包含 4 個部分:
多個 socket
IO 多路復(fù)用程序
文件事件分派器
事件處理器(連接應(yīng)答處理器、命令請求處理器、命令回復(fù)處理器)
多個 socket 可能會并發(fā)產(chǎn)生不同的操作,每個操作對應(yīng)不同的文件事件,但是 IO 多路復(fù)用程序會監(jiān)聽多個 socket,會將產(chǎn)生事件的 socket 放入隊列中排隊,事件分派器每次從隊列中取出一個 socket,根據(jù) socket 的事件類型交給對應(yīng)的事件處理器進行處理。
來看客戶端與 redis 的一次通信過程:
要明白,通信是通過 socket 來完成的,不懂的同學(xué)可以先去看一看 socket 網(wǎng)絡(luò)編程。
首先,redis 服務(wù)端進程初始化的時候,會將 server socket 的 AE_READABLE
事件與連接應(yīng)答處理器關(guān)聯(lián)。
客戶端 socket01 向 redis 進程的 server socket 請求建立連接,此時 server socket 會產(chǎn)生一個 AE_READABLE
事件,IO 多路復(fù)用程序監(jiān)聽到 server socket 產(chǎn)生的事件后,將該 socket 壓入隊列中。文件事件分派器從隊列中獲取 socket,交給連接應(yīng)答處理器。連接應(yīng)答處理器會創(chuàng)建一個能與客戶端通信的 socket01,并將該 socket01 的 AE_READABLE
事件與命令請求處理器關(guān)聯(lián)。
假設(shè)此時客戶端發(fā)送了一個 set key value
請求,此時 redis 中的 socket01 會產(chǎn)生 AE_READABLE
事件,IO 多路復(fù)用程序?qū)?socket01 壓入隊列,此時事件分派器從隊列中獲取到 socket01 產(chǎn)生的 AE_READABLE
事件,由于前面 socket01 的 AE_READABLE
事件已經(jīng)與命令請求處理器關(guān)聯(lián),因此事件分派器將事件交給命令請求處理器來處理。命令請求處理器讀取 socket01 的 key value
并在自己內(nèi)存中完成 key value
的設(shè)置。操作完成后,它會將 socket01 的 AE_WRITABLE
事件與命令回復(fù)處理器關(guān)聯(lián)。
如果此時客戶端準(zhǔn)備好接收返回結(jié)果了,那么 redis 中的 socket01 會產(chǎn)生一個 AE_WRITABLE
事件,同樣壓入隊列中,事件分派器找到相關(guān)聯(lián)的命令回復(fù)處理器,由命令回復(fù)處理器對 socket01 輸入本次操作的一個結(jié)果,比如 ok
,之后解除 socket01 的 AE_WRITABLE
事件與命令回復(fù)處理器的關(guān)聯(lián)。
這樣便完成了一次通信。關(guān)于 Redis 的一次通信過程,推薦讀者閱讀《Redis 設(shè)計與實現(xiàn)——黃健宏》進行系統(tǒng)學(xué)習(xí)。
為啥 redis 單線程模型也能效率這么高?
純內(nèi)存操作。
核心是基于非阻塞的 IO 多路復(fù)用機制。
C 語言實現(xiàn),一般來說,C 語言實現(xiàn)的程序“距離”操作系統(tǒng)更近,執(zhí)行速度相對會更快。
單線程反而避免了多線程的頻繁上下文切換問題,預(yù)防了多線程可能產(chǎn)生的競爭問題。
edis 的并發(fā)競爭問題是什么?如何解決這個問題?了解 redis 事務(wù)的 CAS 方案嗎?
面試官心理分析
這個也是線上非常常見的一個問題,就是多客戶端同時并發(fā)寫一個 key,可能本來應(yīng)該先到的數(shù)據(jù)后到了,導(dǎo)致數(shù)據(jù)版本錯了;或者是多客戶端同時獲取一個 key,修改值之后再寫回去,只要順序錯了,數(shù)據(jù)就錯了。
而且 redis 自己就有天然解決這個問題的 CAS 類的樂觀鎖方案。
面試題剖析
某個時刻,多個系統(tǒng)實例都去更新某個 key。可以基于 zookeeper 實現(xiàn)分布式鎖。每個系統(tǒng)通過 zookeeper 獲取分布式鎖,確保同一時間,只能有一個系統(tǒng)實例在操作某個 key,別人都不允許讀和寫。
你要寫入緩存的數(shù)據(jù),都是從 MySQL 里查出來的,都得寫入 mysql 中,寫入 mysql 中的時候必須保存一個時間戳,從 mysql 查出來的時候,時間戳也查出來。
每次要寫之前,先判斷一下當(dāng)前這個 value 的時間戳是否比緩存里的 value 的時間戳要新。如果是的話,那么可以寫,否則,就不能用舊的數(shù)據(jù)覆蓋新的數(shù)據(jù)。
關(guān)于“Redis中關(guān)于分布式緩存的面試題有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。