這篇文章跟大家分享一下Redis面試題,方便大家查漏補缺,完善知識點。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
#快取
分享Session
訊息佇列系統
分散式鎖定
相關推薦:Redis視頻教學
#純記憶體操作
定期刪除惰性刪除策略
Redis中setnx不支援設定過期時間,做分散式鎖定時要想避免某一客戶端中斷導致死鎖,需設定lock過期時間,在高並發時setnx與expire 無法實現原子操作,如果要用,得在程式碼上顯示的加鎖。使用SET取代SETNX ,相當於SETNX EXPIRE實現了原子性,不必擔心SETNX成功,EXPIRE失敗的問題。
傳統的LRU是使用堆疊的形式,每次都會將最新使用的移入棧頂,但是用堆疊的形式會導致執行select *的時候大量非熱點資料佔領頭部數據,所以需要改進。 Redis每次按key取得一個值的時候,都會更新value中的lru欄位為目前秒等級的時間戳記。 Redis初始的實作演算法很簡單,隨機從dict中取出五個key,淘汰一個lru字段值最小的。在3.0的時候,又改進了一版演算法,首先第一次隨機選取的key都會放入一個pool中(pool的大小為16),pool中的key是按lru大小順序排列的。接下來每次隨機選取的keylru值必須小於pool中最小的lru才會繼續放入,直到將pool放滿。放滿之後,每次如果有新的key需要放入,需要將pool中lru最大的一個key取出。淘汰的時候,直接從pool中選取一個lru最小的值然後將其淘汰。
憑藉經驗,進行預估:例如提前知道了某個活動的開啟,那麼就將此Key作為熱點Key。
服務端收集:在操作redis之前,加入一行程式碼進行資料統計。
抓包進行評估:Redis使用TCP協定與客戶端進行通信,通訊協定採用的是RESP,所以自己寫程式監聽埠也能進行攔截包進行解析。
在proxy層,對每一個 redis 請求進行收集上報。
Redis自帶指令查詢:Redis4.0.4版本提供了redis-cli –hotkeys就能找出熱點Key。 (如果要用Redis自帶指令查詢時,要注意需要先把記憶體逐出策略設定為allkeys-lfu或volatile-lfu,否則會回傳錯誤。進入Redis中使用config set maxmemory-policy allkeys-lfu即可。 )
服務端快取:即將熱點資料快取至服務端的記憶體中.(利用Redis自帶的訊息通知機制來確保Redis和服務端熱點Key的資料一致性,對於熱點Key客戶端建立一個監聽,當熱點Key有更新操作的時候,服務端也隨之更新。)
備份熱點Key:即將熱點Key 隨機數,隨機分配至Redis其他節點。這樣造訪熱點key的時候就不會全部命中到一台機器上了。
使用Redis 高可用架構:使用Redis 叢集來確保Redis 服務不會掛掉
快取時間不一致,給快取的失效時間,加上一個隨機值,避免集體失效
限流降級策略:有一定的備案,例如個性推薦服務不可用了,換成熱點資料推薦服務
在介面做校驗
存null值(快取擊穿加鎖,或設定不過期)
布隆過濾器攔截:將所有可能的查詢key 先映射到布隆過濾器中,查詢時先判斷key是否存在布隆過濾器中,存在才繼續向下執行,如果不存在,則直接返回。布隆過濾器將值進行多次哈希bit存儲,布隆過濾器說某個元素在,可能會被誤判。布隆過濾器說某個元素不在,那一定不在。
Redis為了保證效率,資料快取在了記憶體中,但是會週期性地把更新的數據寫入磁碟或把修改操作寫入追加的記錄檔中,以確保資料的持久化。 Redis的持久化策略有兩種:
RDB:快照形式是直接把記憶體中的資料保存到一個dump的檔案中,定時保存,保存策略。當Redis需要做持久化時,Redis會fork一個子進程,子進程將資料寫到磁碟上一個臨時RDB檔案。當子進程完成寫入臨時檔案後,將原來的RDB替換掉。
AOF:把所有的對Redis的伺服器進行修改的命令都存到一個檔案裡,命令的集合。
使用AOF做持久化,每個寫入指令都透過write函數追加到appendonly.aof。 aof的預設策略是每秒鐘fsync一次,在這種配置下,就算發生故障停機,也最多遺失一秒鐘的資料。缺點是對於相同的資料集來說,AOF的檔案體積通常大於RDB檔案的體積。根據所使用的fsync策略,AOF的速度可能會慢於RDB。 Redis預設是快照RDB的持久化方式。對於主從同步來說,主從剛連接的時候,進行全量同步(RDB);全同步結束後,進行增量同步(AOF)。
Redis 事務的本質是一組指令的集合。事務支援一次執行多個命令,一個事務中所有命令都會被序列化。在事務執行過程,會依照順序串列化執行佇列中的命令,其他客戶端提交的命令請求不會插入到交易執行命令序列中。總結:redis事務就是一次性、順序性、排他性的執行一個佇列中的一系列命令。
Redis事務沒有隔離等級的概念,批次操作在發送EXEC 指令前被放入佇列緩存,並不會實際執行,也就不存在事務內的查詢要看到事務裡的更新,事務外查詢不能看到。在
Redis中,單一指令是原子性執行的,但交易不保證原子性,且沒有回滾。事務中任意指令執行失敗,其餘的指令仍會被執行。
#watch key1 key2 ... : 監視一或多個key,如果在在事務執行之前,被監視的key被其他指令改動,則事務被打斷(類似樂觀鎖)
#multi : 標記一個事務區塊的開始(queued)
#exec : 執行所有事務區塊的命令(一旦執行exec後,先前加的監控鎖定都會被取消掉)
discard : 取消事務,放棄事務區塊中的所有指令
unwatch : 取消watch對所有key的監控
每個哨兵會向其它哨兵、master、slave定時發送訊息,以確認對方是否活著,如果發現對方在指定時間(可配置)內未回應,則暫時認為對方已掛(所謂的”主觀認為宕機”)。
若「哨兵群「中的多數sentinel,都報告某一master沒響應,系統才認為該master"徹底死亡"(即:客觀上的真正down機),通過一定的vote演算法,從剩下的slave節點中,選一台提升為master,然後自動修改相關配置。
Redis的rehash這種漸進式的rehash 避免了集中式rehash帶來的龐大計算量和內存操作,但是需要注意的是redis在進行rehash的時候,正常的訪問請求可能需要做多要訪問兩次hashtable( ht[0], ht[1]),例如鍵值被rehash到新ht1,則需要先存取ht0,如果ht0中找不到,則去ht1中找。
#哈希表中保存的key數量超過了哈希表的大小。
Redis伺服器目前沒有在執行BGSAVE指令(rdb)或BGREWRITEAOF指令,且雜湊表的負載因子大於等於1.
程式設計影片! !
以上是20+道必知必會的Redis面試題總,快來收藏吧! !的詳細內容。更多資訊請關注PHP中文網其他相關文章!