《我們一起進大廠》系列- Redis基礎

敖丙發表於2019-10-28

你知道的越多,你不知道的越多

點贊再看,養成習慣

GitHub上已經開源github.com/JavaFamily,有一線大廠面試點腦圖,歡迎Star和完善

面試開始

一個大腹便便,穿著格子襯衣的中年男子,拿著一個滿是劃痕的mac向你走來,看著快禿頂的頭髮,心想著肯定是尼瑪頂級架構師吧!但是我們腹有詩書氣自華,虛都不虛。

小夥子您好,看你簡歷上寫了你專案裡面用到了Redis,你們為啥用Redis?

心裡忍不住暗罵,這叫啥問題,大家不都是用的這個嘛,但是你不能說出來。

認真回答道:帥氣迷人的面試官您好,因為傳統的關係型資料庫如Mysql已經不能適用所有的場景了,比如秒殺的庫存扣減,APP首頁的訪問流量高峰等等,都很容易把資料庫打崩,所以引入了快取中介軟體,目前市面上比較常用的快取中介軟體有 RedisMemcached 不過中和考慮了他們的優缺點,最後選擇了Redis。

至於更細節的對比朋友們記得查閱Redis 和 Memcached 的區別,比如兩者的優缺點對比和各自的場景,後續我有時間也會寫出來。

那小夥子,我再問你,Redis有哪些資料結構呀?

StringHashListSetSortedSet

這裡我相信99%的讀者都能回答上來Redis的5個基本資料型別。如果回答不出來的小夥伴我們就要加油補課喲,大家知道五種型別最適合的場景更好。

但是,如果你是Redis中高階使用者,而且你要在這次面試中突出你和其他候選人的不同,還需要加上下面幾種資料結構HyperLogLog、Geo、Pub/Sub

如果你還想加分,那你說還玩過Redis Module,像BloomFilter,RedisSearch,Redis-ML,這個時候面試官得眼睛就開始發亮了,心想這個小夥子有點東西啊

注:本人在面試回答到Redis相關的問題的時候,經常提到BloomFilter(布隆過濾器)這玩意的使用場景是真的多,而且用起來是真的香,原理也好理解,看一下文章就可以在面試官面前侃侃而談了,不香麼?下方傳送門 ↓

避免快取擊穿的利器之BloomFilter

如果有大量的key需要設定同一時間過期,一般需要注意什麼?

如果大量的key過期時間設定的過於集中,到過期的那個時間點,Redis可能會出現短暫的卡頓現象。嚴重的話會出現快取雪崩,我們一般需要在時間上加一個隨機值,使得過期時間分散一些。

電商首頁經常會使用定時任務重新整理快取,可能大量的資料失效時間都十分集中,如果失效時間一樣,又剛好在失效的時間點大量使用者湧入,就有可能造成快取雪崩

那你使用過Redis分散式鎖麼,它是什麼回事?

先拿setnx來爭搶鎖,搶到之後,再用expire給鎖加一個過期時間防止鎖忘記了釋放。

這時候對方會告訴你說你回答得不錯,然後接著問如果在setnx之後執行expire之前程式意外crash或者要重啟維護了,那會怎麼樣?

這時候你要給予驚訝的反饋:唉,是喔,這個鎖就永遠得不到釋放了。緊接著你需要抓一抓自己得腦袋,故作思考片刻,好像接下來的結果是你主動思考出來的,然後回答:我記得set指令有非常複雜的引數,這個應該是可以同時把setnxexpire合成一條指令來用的!

對方這時會顯露笑容,心裡開始默唸:嗯,這小子還不錯,開始有點意思了。假如Redis裡面有1億個key,其中有10w個key是以某個固定的已知的字首開頭的,如何將它們全部找出來?

使用keys指令可以掃出指定模式的key列表。

對方接著追問:如果這個redis正在給線上的業務提供服務,那使用keys指令會有什麼問題?

這個時候你要回答Redis關鍵的一個特性:Redis的單執行緒的。keys指令會導致執行緒阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢復。這個時候可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key列表,但是會有一定的重複概率,在客戶端做一次去重就可以了,但是整體所花費的時間會比直接用keys指令長。

不過,增量式迭代命令也不是沒有缺點的: 舉個例子, 使用 SMEMBERS 命令可以返回集合鍵當前包含的所有元素, 但是對於 SCAN 這類增量式迭代命令來說, 因為在對鍵進行增量式迭代的過程中, 鍵可能會被修改, 所以增量式迭代命令只能對被返回的元素提供有限的保證 。

使用過Redis做非同步佇列麼,你是怎麼用的?

一般使用list結構作為佇列,rpush生產訊息,lpop消費訊息。當lpop沒有訊息的時候,要適當sleep一會再重試。

如果對方追問可不可以不用sleep呢?

list還有個指令叫blpop,在沒有訊息的時候,它會阻塞住直到訊息到來。

如果對方接著追問能不能生產一次消費多次呢?

使用pub/sub主題訂閱者模式,可以實現 1:N 的訊息佇列。

如果對方繼續追問 pub/su b有什麼缺點?

在消費者下線的情況下,生產的訊息會丟失,得使用專業的訊息佇列如RocketMQ等。

如果對方究極TM追問Redis如何實現延時佇列?

這一套連招下來,我估計現在你很想把面試官一棒打死(面試官自己都想打死自己了怎麼問了這麼多自己都不知道的),如果你手上有一根棒球棍的話,但是你很剋制。平復一下激動的內心,然後神態自若的回答道:使用sortedset,拿時間戳作為score,訊息內容作為key呼叫zadd來生產訊息,消費者用zrangebyscore指令獲取N秒之前的資料輪詢進行處理。

到這裡,面試官暗地裡已經對你豎起了大拇指。並且已經默默給了你A+,但是他不知道的是此刻你卻豎起了中指,在椅子背後。

Redis是怎麼持久化的?服務主從資料怎麼互動的?

RDB做映象全量持久化,AOF做增量持久化。因為RDB會耗費較長時間,不夠實時,在停機的時候會導致大量丟失資料,所以需要AOF來配合使用。在redis例項重啟時,會使用RDB持久化檔案重新構建記憶體,再使用AOF重放近期的操作指令來實現完整恢復重啟之前的狀態。

這裡很好理解,把RDB理解為一整個表全量的資料,AOF理解為每次操作的日誌就好了,伺服器重啟的時候先把表的資料全部搞進去,但是他可能不完整,你再回放一下日誌,資料不就完整了嘛。不過Redis本身的機制是 AOF持久化開啟且存在AOF檔案時,優先載入AOF檔案;AOF關閉或者AOF檔案不存在時,載入RDB檔案;載入AOF/RDB檔案城後,Redis啟動成功; AOF/RDB檔案存在錯誤時,Redis啟動失敗並列印錯誤資訊

對方追問那如果突然機器掉電會怎樣?

取決於AOF日誌sync屬性的配置,如果不要求效能,在每條寫指令時都sync一下磁碟,就不會丟失資料。但是在高效能的要求下每次都sync是不現實的,一般都使用定時sync,比如1s1次,這個時候最多就會丟失1s的資料。

對方追問RDB的原理是什麼?

你給出兩個詞彙就可以了,fork和cow。fork是指redis通過建立子程式來進行RDB操作,cow指的是copy on write,子程式建立後,父子程式共享資料段,父程式繼續提供讀寫服務,寫髒的頁面資料會逐漸和子程式分離開來。

注:回答這個問題的時候,如果你還能說出AOF和RDB的優缺點,我覺得我是面試官在這個問題上我會給你點贊,兩者其實區別還是很大的,而且涉及到Redis叢集的資料同步問題等等。想了解的夥伴也可以留言,我會專門寫一篇來介紹的。

Pipeline有什麼好處,為什麼要用pipeline?

可以將多次IO往返的時間縮減為一次,前提是pipeline執行的指令之間沒有因果相關性。使用redis-benchmark進行壓測的時候可以發現影響redis的QPS峰值的一個重要因素是pipeline批次指令的數目。

Redis的同步機制瞭解麼?

Redis可以使用主從同步,從從同步。第一次同步時,主節點做一次bgsave,並同時將後續修改操作記錄到記憶體buffer,待完成後將RDB檔案全量同步到複製節點,複製節點接受完成後將RDB映象載入到記憶體。載入完成後,再通知主節點將期間修改的操作記錄同步到複製節點進行重放就完成了同步過程。後續的增量資料通過AOF日誌同步即可,有點類似資料庫的binlog。

是否使用過Redis叢集,叢集的高可用怎麼保證,叢集的原理是什麼?

Redis Sentinal 著眼於高可用,在master當機時會自動將slave提升為master,繼續提供服務。

Redis Cluster 著眼於擴充套件性,在單個redis記憶體不足時,使用Cluster進行分片儲存。

面試結束

小夥子你可以的,什麼時候有時間來上班啊,要不明天就來吧?

你強裝鎮定,這麼急啊我還需要租房,要不下禮拜一吧。

好的 心想這小子這麼NB是不是很多Offer在手上,不行我得叫hr給他加錢。

能撐到最後,你自己都忍不住自己給自己點個讚了!

暗示點贊,每次都看了不點贊,你們想白嫖我麼?你們好壞喲,不過我喜歡)。

總結

在技術面試的時候,不管是Redis還是什麼問題,如果你能舉出實際的例子,或者是直接說自己開發過程的問題和收穫會給面試官的印象分會加很多,回答邏輯性也要強一點,不要東一點西一點,容易把自己都繞暈的。

還有一點就是我問你為啥用Redis你不要一上來就直接回答問題了,你可以這樣回答:

帥氣的面試官您好,首先我們的專案DB遇到了瓶頸,特別是秒殺和熱點資料這樣的場景DB基本上就扛不住了,那就需要快取中介軟體的加入了,目前市面上有的快取中介軟體有 RedisMemcached ,他們的優缺點……,綜合這些然後再結合我們專案特點,最後我們在技術選型的時候選了誰。

如果你這樣有條不紊,有理有據的回答了我的問題而且還說出這麼多我問題外的知識點,我會覺得你不只是一個會寫程式碼的人,你邏輯清晰,你對技術選型,對中介軟體對專案都有自己的理解和思考,說白了就是你的offer有戲了。

鳴謝

老錢:掌閱服務端技術專家,網際網路分散式高併發技術十年老兵,現任位元組跳動技術專家。

以Redis系列為開始是他給的建議,並且允許我以他其中一篇的風格和大部分內容為自己開始寫部落格的風格。

點關注,不迷路

好了各位,以上就是這篇文章的全部內容了,能看到這裡的人呀,都是人才

我後面會每週都更新幾篇一線網際網路大廠面試和常用技術棧相關的文章,非常感謝人才們能看到這裡,如果這個文章寫得還不錯,覺得「敖丙」我有點東西的話 求點贊? 求關注❤️ 求分享? 對暖男我來說真的 非常有用!!!

白嫖不好,創作不易,各位的支援和認可,就是我創作的最大動力,我們下篇文章見!

敖丙 | 文 【原創】

如果本篇部落格有任何錯誤,請批評指教,不勝感激 !


文章每週持續更新,可以微信搜尋「 三太子敖丙 」第一時間閱讀和催更(比部落格早一到兩篇喲),本文 GitHub github.com/JavaFamily 已經收錄,有一線大廠面試點思維導圖,也整理了很多我的文件,歡迎Star和完善,大家面試可以參照考點複習,希望我們一起有點東西。

相關文章