<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:看你簡歷上有寫Redis,來請講下

          共 3596字,需瀏覽 8分鐘

           ·

          2022-02-11 10:34

          Redis是面試中繞不過的檻,只要在簡歷中寫了用過Redis,肯定逃不過。今天我們就來模擬一下面試官在Redis這個話題上是如何一步一步深入,全面考察候選人對于Redis的掌握情況。

          小張:

          面試官,你好。我是來參加面試的。

          面試官:

          你好,小張。我看了你的簡歷,熟練掌握Redis,那么我就隨便問你幾個Redis相關(guān)的問題吧。首先我的問題是,Redis是單線程還是多線程呢?

          小張:

          Redis不同版本之間采用的線程模型是不一樣的,在Redis4.0版本之前使用的是單線程模型,在4.0版本之后增加了多線程的支持。

          在4.0之前雖然我們說Redis是單線程,也只是說它的網(wǎng)絡(luò)I/O線程以及Set 和 Get操作是由一個線程完成的。但是Redis的持久化、集群同步還是使用其他線程來完成。

          4.0之后添加了多線程的支持,主要是體現(xiàn)在大數(shù)據(jù)的異步刪除功能上,例如 unlink keyflushdb async、flushall async

          面試官:

          回答的很好,那為什么Redis在4.0之前會選擇使用單線程?而且使用單線程還那么快?

          小張:

          選擇單線程個人覺得主要是使用簡單,不存在鎖競爭,可以在無鎖的情況下完成所有操作,不存在死鎖和線程切換帶來的性能和時間上的開銷,但同時單線程也不能完全發(fā)揮出多核CPU的性能。

          至于為什么單線程那么快我覺得主要有以下幾個原因:

          1. Redis 的大部分操作都在內(nèi)存中完成,內(nèi)存中的執(zhí)行效率本身就很快,并且采用了高效的數(shù)據(jù)結(jié)構(gòu),比如哈希表和跳表。
          2. 使用單線程避免了多線程的競爭,省去了多線程切換帶來的時間和性能開銷,并且不會出現(xiàn)死鎖。
          3. 采用 I/O 多路復(fù)用機制處理大量客戶端的Socket請求,因為這是基于非阻塞的 I/O 模型,這就讓Redis可以高效地進行網(wǎng)絡(luò)通信,I/O的讀寫流程也不再阻塞。

          面試官:

          不錯,那Redis是如何實現(xiàn)數(shù)據(jù)不丟失的呢?

          小張:

          Redis數(shù)據(jù)是存儲在內(nèi)存中的,為了保證Redis數(shù)據(jù)不丟失,那就要把數(shù)據(jù)從內(nèi)存存儲到磁盤上,以便在服務(wù)器重啟后還能夠從磁盤中恢復(fù)原有數(shù)據(jù),這就是Redis的數(shù)據(jù)持久化。Redis數(shù)據(jù)持久化有三種方式。

          • AOF 日志(Append Only File,文件追加方式):記錄所有的操作命令,并以文本的形式追加到文件中。

          • RDB 快照(Redis DataBase):將某一個時刻的內(nèi)存數(shù)據(jù),以二進制的方式寫入磁盤。

          • 混合持久化方式:Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的優(yōu)點。

          面試官:

          那你分別說說 AOF和 RDB的實現(xiàn)原理吧。

          小張:

          AOF采用的是寫后日志的方式,Redis先執(zhí)行命令把數(shù)據(jù)寫入內(nèi)存,然后再記錄日志到文件中。AOF日志記錄的是操作命令,不是實際的數(shù)據(jù),如果采用AOF方法做故障恢復(fù)時需要將全量日志都執(zhí)行一遍。

          RDB采用的是內(nèi)存快照的方式,它記錄的是某一時刻的數(shù)據(jù),而不是操作,所以采用RDB方法做故障恢復(fù)時只需要直接把RDB文件讀入內(nèi)存即可,實現(xiàn)快速恢復(fù)。

          面試官:

          你剛提到了AOF采用的是 “寫后日志” 的方式,我們平時用的MySQL則采用的是 “寫前日志”,那 Redis為什么要先執(zhí)行命令,再把數(shù)據(jù)寫入日志呢?

          小張:額頭開始冒汗,問的是些啥問題呀。。。

          額,這個主要是由于Redis在寫入日志之前,不對命令進行語法檢查,所以只記錄執(zhí)行成功的命令,避免出現(xiàn)記錄錯誤命令的情況,而且在命令執(zhí)行后再寫日志不會阻塞當(dāng)前的寫操作。

          面試官:

          后寫日志又有什么風(fēng)險呢?

          小張:

          我... 這個我不會。

          面試官:

          好吧,后寫日志主要有兩個風(fēng)險可能會發(fā)生:

          • 數(shù)據(jù)可能會丟失:如果 Redis 剛執(zhí)行完命令,此時發(fā)生故障宕機,會導(dǎo)致這條命令存在丟失的風(fēng)險。
          • 可能阻塞其他操作:AOF 日志其實也是在主線程中執(zhí)行,所以當(dāng) Redis 把日志文件寫入磁盤的時候,還是會阻塞后續(xù)的操作無法執(zhí)行。

          我還有個問題是 RDB做快照時會阻塞線程嗎?

          小張:

          Redis 提供了兩個命令來生成 RDB 快照文件,分別是 savebgsavesave 命令在主線程中執(zhí)行,會導(dǎo)致阻塞。而 bgsave 命令則會創(chuàng)建一個子進程,用于寫入 RDB 文件的操作,避免了對主線程的阻塞,這也是 Redis RDB 的默認配置。

          面試官:

          RDB 做快照的時候數(shù)據(jù)能修改嗎?

          小張:

          save是同步的會阻塞客戶端命令,bgsave的時候是可以修改的。

          面試官:

          那Redis是怎么解決在bgsave做快照的時候允許數(shù)據(jù)修改呢?

          小張:(你咋還問。。。我?不會?。。?/p>

          額,這個我不太清楚...

          面試官:

          這里主要是利用bgsave的子線程實現(xiàn)的,具體操作如下:

          • 如果主線程執(zhí)行讀操作,則主線程和 bgsave 子進程互相不影響;

          • 如果主線程執(zhí)行寫操作,則被修改的數(shù)據(jù)會復(fù)制一份副本,然后 bgsave子進程會把該副本數(shù)據(jù)寫入 RDB 文件,在這個過程中,主線程仍然可以直接修改原來的數(shù)據(jù)。

          要注意,Redis 對 RDB 的執(zhí)行頻率非常重要,因為這會影響快照數(shù)據(jù)的完整性以及 Redis 的穩(wěn)定性,所以在 Redis 4.0 后,增加了 AOF 和 RDB 混合的數(shù)據(jù)持久化機制: 把數(shù)據(jù)以 RDB 的方式寫入文件,再將后續(xù)的操作命令以 AOF 的格式存入文件,既保證了 Redis 重啟速度,又降低數(shù)據(jù)丟失風(fēng)險。

          小張:

          學(xué)到了學(xué)到了。

          面試官:

          那你再跟我說說Redis如何實現(xiàn)高可用吧?

          小張:

          Redis實現(xiàn)高可用主要有三種方式:主從復(fù)制、哨兵模式,以及 Redis 集群。

          主從復(fù)制

          將從前的一臺 Redis 服務(wù)器,同步數(shù)據(jù)到多臺從 Redis 服務(wù)器上,即一主多從的模式,這個跟MySQL主從復(fù)制的原理一樣。

          哨兵模式

          使用 Redis 主從服務(wù)的時候,會有一個問題,就是當(dāng) Redis 的主從服務(wù)器出現(xiàn)故障宕機時,需要手動進行恢復(fù),為了解決這個問題,Redis 增加了哨兵模式(因為哨兵模式做到了可以監(jiān)控主從服務(wù)器,并且提供自動容災(zāi)恢復(fù)的功能)。

          Redis Cluster(集群)

          Redis Cluster 是一種分布式去中心化的運行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它將數(shù)據(jù)分布在不同的服務(wù)器上,以此來降低系統(tǒng)對單主節(jié)點的依賴,從而提高 Redis 服務(wù)的讀寫性能。

          面試官:

          使用哨兵模式在數(shù)據(jù)上有副本數(shù)據(jù)做保證,在可用性上又有哨兵監(jiān)控,一旦master宕機會選舉salve節(jié)點為master節(jié)點,這種已經(jīng)滿足了我們的生產(chǎn)環(huán)境需要,那為什么還需要使用集群模式呢?

          小張:

          額,哨兵模式歸根節(jié)點還是主從模式,在主從模式下我們可以通過增加salve節(jié)點來擴展讀并發(fā)能力,但是沒辦法擴展寫能力和存儲能力,存儲能力只能是master節(jié)點能夠承載的上限。所以為了擴展寫能力和存儲能力,我們就需要引入集群模式。

          面試官:

          集群中那么多Master節(jié)點,redis cluster在存儲的時候如何確定選擇哪個節(jié)點呢?

          小張:

          這應(yīng)該是使用了某種hash算法,但是我不太清楚。。。

          面試官:

          那好,今天的面試就到這里吧,你先回去等我們的面試通知。

          小張:

          好的,謝謝面試官,你能告訴我redis cluster怎么實現(xiàn)節(jié)點選擇的嗎?

          面試官:

          Redis Cluster采用的是類一致性哈希算法實現(xiàn)節(jié)點選擇的,至于什么是一致性哈希算法你自己回去看看。

          Redis Cluster將自己分成了16384個Slot(槽位),哈希槽類似于數(shù)據(jù)分區(qū),每個鍵值對都會根據(jù)它的 key,被映射到一個哈希槽中,具體執(zhí)行過程分為兩大步。

          • 根據(jù)鍵值對的 key,按照 CRC16 算法計算一個 16 bit 的值。

          • 再用 16bit 值對 16384 取模,得到 0~16383 范圍內(nèi)的模數(shù),每個模數(shù)代表一個相應(yīng)編號的哈希槽。

          每個Redis節(jié)點負責(zé)處理一部分槽位,加入你有三個master節(jié)點 ABC,每個節(jié)點負責(zé)的槽位如下:

          節(jié)點處理槽位
          A0-5000
          B5001 - 10000
          C10001 - 16383

          這樣就實現(xiàn)了cluster節(jié)點的選擇。



          程序汪資料鏈接

          程序汪接的7個私活都在這里,經(jīng)驗整理

          Java項目分享 最新整理全集,找項目不累啦 06版

          堪稱神級的Spring Boot手冊,從基礎(chǔ)入門到實戰(zhàn)進階

          臥槽!字節(jié)跳動《算法中文手冊》火了,完整版 PDF 開放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!

          字節(jié)跳動總結(jié)的設(shè)計模式 PDF 火了,完整版開放下載!

          歡迎添加程序汪個人微信 itwang008? 進粉絲群或圍觀朋友圈

          瀏覽 157
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品成人7777777 | 国产精品操 | 亚洲精选一区二区三区 | 五月丁香婷婷国产 | 日韩高清无码18 |