《吊打面試官》系列-Redis基礎

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

點贊再看,養成習慣面試

前言

Redis在互聯網技術存儲方面使用如此普遍,幾乎全部的後端技術面試官都要在Redis的使用和原理方面對小夥伴們進行360°的刁難。做爲一個在互聯網公司面一次拿一次offer的麪霸(請容許我使用一下誇張的修辭手法),戰勝了無數競爭對手,每次都只能看到無數落寞的身影失望的離開,略感愧疚,在一個寂寞難耐的夜晚,我痛定思痛,決定開始寫《吊打面試官》系列,但願能幫助各位讀者之後面試勢如破竹,對面試官進行360°的反擊,吊打問你的面試官,讓一同面試的同僚鎩羽而歸,瘋狂收割大廠offer!redis

面試開始

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

小夥子您好,看你簡歷上寫了你項目裏面用到了Redis,大家爲啥用Redis?

內心忍不住暗罵,這叫啥問題,你們不都是用的這個嘛,可是你不能說出來。sql

認真回答道:帥氣迷人的面試官您好,由於傳統的關係型數據庫如Mysql已經不能適用全部的場景了,好比秒殺的庫存扣減,APP首頁的訪問流量高峯等等,都很容易把數據庫打崩,因此引入了緩存中間件,目前市面上比較經常使用的緩存中間件有Redis 和 Memcached 不過中和考慮了他們的優缺點,最後選擇了Redis。數據庫

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

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

字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。緩存

這裏我相信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指令有很是複雜的參數,這個應該是能夠同時把setnx和expire合成一條指令來用的!

對方這時會顯露笑容,內心開始默唸:嗯,這小子還不錯,開始有點意思了。

假如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基本上就扛不住了,那就須要緩存中間件的加入了,目前市面上有的緩存中間件有 Redis 和 Memcached ,他們的優缺點......,綜合這些而後再結合咱們項目特色,最後咱們在技術選型的時候選了誰。

若是你這樣有條不紊,有理有據的回答了個人問題並且還說出這麼多我問題外的知識點,我會以爲你不僅是一個會寫代碼的人,你邏輯清晰,你對技術選型,對中間件對項目都有本身的理解和思考,說白了就是你的offer有戲了。

好了 以上就是這篇文章的所有內容了,我後面會不斷更新《吊打面試官》系列和Java技術棧相關的文章。若是你有什麼想知道的,也能夠留言給我,我一有時間就會寫出來,咱們共同進步。

很是感謝您能看到這裏,若是這個文章寫得還不錯的話 求點贊 求關注 求分享 求留言 各位的支持和承認,就是我創做的最大動力,OK各位咱們下期見!

敖丙 | 文


JavaFamily 後面會持續更新《吊打面試官》系列能夠關注個人公衆號第一時間閱讀,我也是個新人,不過不影響咱們一塊兒進步。
相關文章
相關標籤/搜索