您好,登錄后才能下訂單哦!
這篇文章主要講解了“redis面試中常被問(wèn)到的重點(diǎn)有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“redis面試中常被問(wèn)到的重點(diǎn)有哪些”吧!
Redis是面試中繞不過(guò)的檻,只要在簡(jiǎn)歷中寫(xiě)了用過(guò)Redis,肯定逃不過(guò)。
小張:
面試官,你好。我是來(lái)參加面試的。
面試官:
你好,小張。我看了你的簡(jiǎn)歷,熟練掌握Redis,那么我就隨便問(wèn)你幾個(gè)Redis相關(guān)的問(wèn)題吧。首先我的問(wèn)題是,Redis是單線程還是多線程呢?
小張:
Redis不同版本之間采用的線程模型是不一樣的,在Redis4.0版本之前使用的是單線程模型,在4.0版本之后增加了多線程的支持。
在4.0之前雖然我們說(shuō)Redis是單線程,也只是說(shuō)它的網(wǎng)絡(luò)I/O線程以及Set 和 Get操作是由一個(gè)線程完成的。但是Redis的持久化、集群同步還是使用其他線程來(lái)完成。
4.0之后添加了多線程的支持,主要是體現(xiàn)在大數(shù)據(jù)的異步刪除功能上,例如 unlink key
、flushdb async
、flushall async
等
面試官:
回答的很好,那為什么Redis在4.0之前會(huì)選擇使用單線程?而且使用單線程還那么快?
小張:
選擇單線程個(gè)人覺(jué)得主要是使用簡(jiǎn)單,不存在鎖競(jìng)爭(zhēng),可以在無(wú)鎖的情況下完成所有操作,不存在死鎖和線程切換帶來(lái)的性能和時(shí)間上的開(kāi)銷,但同時(shí)單線程也不能完全發(fā)揮出多核CPU的性能。
至于為什么單線程那么快我覺(jué)得主要有以下幾個(gè)原因:
Redis 的大部分操作都在內(nèi)存中完成,內(nèi)存中的執(zhí)行效率本身就很快,并且采用了高效的數(shù)據(jù)結(jié)構(gòu),比如哈希表和跳表。
使用單線程避免了多線程的競(jìng)爭(zhēng),省去了多線程切換帶來(lái)的時(shí)間和性能開(kāi)銷,并且不會(huì)出現(xiàn)死鎖。
采用 I/O 多路復(fù)用機(jī)制處理大量客戶端的Socket請(qǐng)求,因?yàn)檫@是基于非阻塞的 I/O 模型,這就讓Redis可以高效地進(jìn)行網(wǎng)絡(luò)通信,I/O的讀寫(xiě)流程也不再阻塞。
面試官:
不錯(cuò),那Redis是如何實(shí)現(xiàn)數(shù)據(jù)不丟失的呢?
小張:
Redis數(shù)據(jù)是存儲(chǔ)在內(nèi)存中的,為了保證Redis數(shù)據(jù)不丟失,那就要把數(shù)據(jù)從內(nèi)存存儲(chǔ)到磁盤上,以便在服務(wù)器重啟后還能夠從磁盤中恢復(fù)原有數(shù)據(jù),這就是Redis的數(shù)據(jù)持久化。Redis數(shù)據(jù)持久化有三種方式。
AOF 日志(Append Only File,文件追加方式):記錄所有的操作命令,并以文本的形式追加到文件中。
RDB 快照(Redis DataBase):將某一個(gè)時(shí)刻的內(nèi)存數(shù)據(jù),以二進(jìn)制的方式寫(xiě)入磁盤。
混合持久化方式:Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的優(yōu)點(diǎn)。
面試官:
那你分別說(shuō)說(shuō) AOF和 RDB的實(shí)現(xiàn)原理吧。
小張:
AOF采用的是寫(xiě)后日志的方式,Redis先執(zhí)行命令把數(shù)據(jù)寫(xiě)入內(nèi)存,然后再記錄日志到文件中。AOF日志記錄的是操作命令,不是實(shí)際的數(shù)據(jù),如果采用AOF方法做故障恢復(fù)時(shí)需要將全量日志都執(zhí)行一遍。
RDB采用的是內(nèi)存快照的方式,它記錄的是某一時(shí)刻的數(shù)據(jù),而不是操作,所以采用RDB方法做故障恢復(fù)時(shí)只需要直接把RDB文件讀入內(nèi)存即可,實(shí)現(xiàn)快速恢復(fù)。
面試官:
你剛提到了AOF采用的是 “寫(xiě)后日志” 的方式,我們平時(shí)用的MySQL則采用的是 “寫(xiě)前日志”,那 Redis為什么要先執(zhí)行命令,再把數(shù)據(jù)寫(xiě)入日志呢?
小張:額頭開(kāi)始冒汗,問(wèn)的是些啥問(wèn)題呀。。。
額,這個(gè)主要是由于Redis在寫(xiě)入日志之前,不對(duì)命令進(jìn)行語(yǔ)法檢查,所以只記錄執(zhí)行成功的命令,避免出現(xiàn)記錄錯(cuò)誤命令的情況,而且在命令執(zhí)行后再寫(xiě)日志不會(huì)阻塞當(dāng)前的寫(xiě)操作。
面試官:
那 后寫(xiě)日志又有什么風(fēng)險(xiǎn)呢?
小張:
我... 這個(gè)我不會(huì)。
面試官:
好吧,后寫(xiě)日志主要有兩個(gè)風(fēng)險(xiǎn)可能會(huì)發(fā)生:
數(shù)據(jù)可能會(huì)丟失:如果 Redis 剛執(zhí)行完命令,此時(shí)發(fā)生故障宕機(jī),會(huì)導(dǎo)致這條命令存在丟失的風(fēng)險(xiǎn)。
可能阻塞其他操作:AOF 日志其實(shí)也是在主線程中執(zhí)行,所以當(dāng) Redis 把日志文件寫(xiě)入磁盤的時(shí)候,還是會(huì)阻塞后續(xù)的操作無(wú)法執(zhí)行。
我還有個(gè)問(wèn)題是 RDB做快照時(shí)會(huì)阻塞線程嗎?
小張:
Redis 提供了兩個(gè)命令來(lái)生成 RDB 快照文件,分別是 save 和 bgsave。save 命令在主線程中執(zhí)行,會(huì)導(dǎo)致阻塞。而 bgsave 命令則會(huì)創(chuàng)建一個(gè)子進(jìn)程,用于寫(xiě)入 RDB 文件的操作,避免了對(duì)主線程的阻塞,這也是 Redis RDB 的默認(rèn)配置。
面試官:
RDB 做快照的時(shí)候數(shù)據(jù)能修改嗎?
小張:
save是同步的會(huì)阻塞客戶端命令,bgsave的時(shí)候是可以修改的。
面試官:
那Redis是怎么解決在bgsave做快照的時(shí)候允許數(shù)據(jù)修改呢?
小張:(你咋還問(wèn)。。。我?不會(huì)啊?。?/p>
額,這個(gè)我不太清楚...
面試官:
這里主要是利用bgsave
的子線程實(shí)現(xiàn)的,具體操作如下:
如果主線程執(zhí)行讀操作,則主線程和 bgsave
子進(jìn)程互相不影響;
如果主線程執(zhí)行寫(xiě)操作,則被修改的數(shù)據(jù)會(huì)復(fù)制一份副本,然后 bgsave
子進(jìn)程會(huì)把該副本數(shù)據(jù)寫(xiě)入 RDB 文件,在這個(gè)過(guò)程中,主線程仍然可以直接修改原來(lái)的數(shù)據(jù)。
要注意,Redis 對(duì) RDB 的執(zhí)行頻率非常重要,因?yàn)檫@會(huì)影響快照數(shù)據(jù)的完整性以及 Redis 的穩(wěn)定性,所以在 Redis 4.0 后,增加了 AOF 和 RDB 混合的數(shù)據(jù)持久化機(jī)制: 把數(shù)據(jù)以 RDB 的方式寫(xiě)入文件,再將后續(xù)的操作命令以 AOF 的格式存入文件,既保證了 Redis 重啟速度,又降低數(shù)據(jù)丟失風(fēng)險(xiǎn)。
小張:
學(xué)到了學(xué)到了。
面試官:
那你再跟我說(shuō)說(shuō)Redis如何實(shí)現(xiàn)高可用吧?
小張:
Redis實(shí)現(xiàn)高可用主要有三種方式:主從復(fù)制、哨兵模式,以及 Redis 集群。
主從復(fù)制
將從前的一臺(tái) Redis 服務(wù)器,同步數(shù)據(jù)到多臺(tái)從 Redis 服務(wù)器上,即一主多從的模式,這個(gè)跟MySQL主從復(fù)制的原理一樣。
哨兵模式
使用 Redis 主從服務(wù)的時(shí)候,會(huì)有一個(gè)問(wèn)題,就是當(dāng) Redis 的主從服務(wù)器出現(xiàn)故障宕機(jī)時(shí),需要手動(dòng)進(jìn)行恢復(fù),為了解決這個(gè)問(wèn)題,Redis 增加了哨兵模式(因?yàn)樯诒J阶龅搅丝梢员O(jiān)控主從服務(wù)器,并且提供自動(dòng)容災(zāi)恢復(fù)的功能)。
Redis Cluster(集群)
Redis Cluster 是一種分布式去中心化的運(yùn)行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它將數(shù)據(jù)分布在不同的服務(wù)器上,以此來(lái)降低系統(tǒng)對(duì)單主節(jié)點(diǎn)的依賴,從而提高 Redis 服務(wù)的讀寫(xiě)性能。
面試官:
使用哨兵模式在數(shù)據(jù)上有副本數(shù)據(jù)做保證,在可用性上又有哨兵監(jiān)控,一旦master宕機(jī)會(huì)選舉salve節(jié)點(diǎn)為master節(jié)點(diǎn),這種已經(jīng)滿足了我們的生產(chǎn)環(huán)境需要,那為什么還需要使用集群模式呢?
小張:
額,哨兵模式歸根節(jié)點(diǎn)還是主從模式,在主從模式下我們可以通過(guò)增加salve節(jié)點(diǎn)來(lái)擴(kuò)展讀并發(fā)能力,但是沒(méi)辦法擴(kuò)展寫(xiě)能力和存儲(chǔ)能力,存儲(chǔ)能力只能是master節(jié)點(diǎn)能夠承載的上限。所以為了擴(kuò)展寫(xiě)能力和存儲(chǔ)能力,我們就需要引入集群模式。
面試官:
集群中那么多Master節(jié)點(diǎn),redis cluster在存儲(chǔ)的時(shí)候如何確定選擇哪個(gè)節(jié)點(diǎn)呢?
小張:
這應(yīng)該是使用了某種hash算法,但是我不太清楚。。。
面試官:
那好,今天的面試就到這里吧,你先回去等我們的面試通知。
小張:
好的,謝謝面試官,你能告訴我redis cluster怎么實(shí)現(xiàn)節(jié)點(diǎn)選擇的嗎?
面試官:
Redis Cluster采用的是類一致性哈希算法實(shí)現(xiàn)節(jié)點(diǎn)選擇的,至于什么是一致性哈希算法你自己回去看看。
Redis Cluster將自己分成了16384個(gè)Slot(槽位),哈希槽類似于數(shù)據(jù)分區(qū),每個(gè)鍵值對(duì)都會(huì)根據(jù)它的 key,被映射到一個(gè)哈希槽中,具體執(zhí)行過(guò)程分為兩大步。
根據(jù)鍵值對(duì)的 key,按照 CRC16 算法計(jì)算一個(gè) 16 bit 的值。
再用 16bit 值對(duì) 16384 取模,得到 0~16383 范圍內(nèi)的模數(shù),每個(gè)模數(shù)代表一個(gè)相應(yīng)編號(hào)的哈希槽。
每個(gè)Redis節(jié)點(diǎn)負(fù)責(zé)處理一部分槽位,加入你有三個(gè)master節(jié)點(diǎn) ABC,每個(gè)節(jié)點(diǎn)負(fù)責(zé)的槽位如下:
這樣就實(shí)現(xiàn)了cluster節(jié)點(diǎn)的選擇。
感謝各位的閱讀,以上就是“redis面試中常被問(wèn)到的重點(diǎn)有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)redis面試中常被問(wèn)到的重點(diǎn)有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(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)容。