java架構之路-(Redis專題)redis面試助力滿分+

1.Redis支持的數據類型?

答:五種,在第一節redis相關的博客我就說過,String,Hash,List,Set,zSet,也就是我們的字符串,哈希,列表,集合,有序集合五種。結構圖如下。

 2.什麼是Redis持久化?Redis有哪幾種持久化方式?優缺點是什麼?

答:Redis持久化主要分爲三種,RDB、AOF還有我們的混合持久化,RDB是一個二進制文件,AOF是保存我們的每一次操作的命令,默認是使用RDB的持久化方式。RDB,二進制文件,速度快,但是數據安全性差,可能造成數據的丟失,AOF,命令文件,速度慢,數據安全性視配置文件而定,相對要更安全一些,數據不容易丟失,BGREWRITEAOF重寫可以壓縮我們已有的AOF文件,混合持久化模式就是以RDB和AOF共同使用的。

 3.Redis 有哪些架構模式?講講各自的特點

答:主從模式,一般是一個主節點,一或多個從節點,爲了保證我們的主節點宕機後,數據不丟失,我們將主節點的數據備份到從節點,從節點並不進行實際操作,只做實時同步操作,並不能起到高併發的目的。

  哨兵模式,一個哨兵集羣和一組主從架構組成。比主從更好的是當我們的主節點宕機以後,哨兵會主動選舉出一個主節點繼續向外提供服務。

  集羣架構,由很多個小主從聚集在一起,一起向外提供服務的,將16384個卡槽切分存儲,並不是一個強一致性的集羣架構,每一個小主從節點內會存在選舉機制,保證對外的高可用架構。

 4.Redis常用命令?

  答:setnx,單次插入,incr,DECR原子加減,lpush列表左側插入,rpush列表右側插入,rpop列表右側移除,blpop key timeout 從列表key的表頭(最左側)彈出第一個元素,sadd集合中添加元素,sismember判斷元素是否在集合中,sinter交集,sunion並集,sdiff差集,zadd有序集合添加元素。

 5.使用過Redis分佈式鎖麼,它是怎麼實現的?

  答:用過分佈式鎖,用setnx來簡單實現的,設置setnx,也就是鎖的爭搶,設置成功的即爲拿到鎖的,鎖需要設置最大等待時間,並設置方法內的唯一UUID作爲Value,防止其它線程解鎖。方法結束以後,用finnal來解鎖,需要判斷value值爲當前UUID纔可以解鎖,這樣就簡單實現了一個分佈式的鎖,爲了保證原子性操作可以採用lua腳本來執行中間判斷步驟。還有很成熟的redisson來設置我們的分佈式鎖,也解決了我們上面最大等待時間多久合適的爭議。redisson底層是這樣來做的,我們設置了一個線程鎖,超時時間比如設置了30秒,方法開始執行,這時redisson會開啓一個分線程,來查詢主線程的方法是否執行完成,大概是沒30/3秒執行一次,即使到了30秒還沒有執行完,redisson也不會將鎖釋放掉,會繼續給予鎖10秒的生命時間,來繼續使主線程正常運行,直到時間加到主線程執行完成爲止。

6.使用過Redis做異步隊列麼,你是怎麼用的?有什麼缺點?

  答:用過,用列表數據來實現的。大致就是左側進入lpush,右側彈出brpop,或者相反的方向也是可以的,但是用我們的redis實現的消息隊列,消息的發佈是無狀態的,無法保證可達,若訂閱者在發送者發佈消息期間下線,之後我們再上線將無法接受到剛纔發送的消息,解決辦法就是使用消息隊列

 7.什麼是緩存穿透?如何避免?什麼是緩存雪崩?何如避免?

  答:緩存擊穿是指經過緩存層並沒有得到我們想要的數據,請求會向下請求我們的數據庫,這就是緩存擊穿,我們可以在每次請求數據庫返回時做一個保存操作,即使沒有值也保存一下,記得設置好超時時間,現在沒有值,不代表永遠沒有值。

緩存雪崩是指redis宕機造成服務無法繼續使用,或者大量的命令阻塞的redis,造成假死現象,使得請求直接訪問我們的數據庫,請求量巨大,可能壓垮我們的數據服務器,可以使用高可用的架構來做redis服務,比如哨兵架構,集羣架構,避免用單機的redis來作爲緩存服務,對於併發量超大的情況我們可以使用限流的方式來控制。比如hystrix 

 8.redis的單線程爲什麼那麼快

  答:因爲它所有的數據都在內存中,所有的運算都是內存級別的運算,而且單線程避免了多線程的切換中性能損耗的問題。

 9.Redis有哪幾種數據淘汰策略?

  答:默認策略是volatile-lru,即超過最大內存後,在過期鍵中使用lru算法進行key的剔除,保證不過期數據不被刪除,但是可能會出現OOM問題。

  其他策略如下:

allkeys-lru:根據LRU算法刪除鍵,不管數據有沒有設置超時屬性,直到騰出足夠空間爲止。

allkeys-random:隨機刪除所有鍵,直到騰出足夠空間爲止。

volatile-random: 隨機刪除過期鍵,直到騰出足夠空間爲止。

volatile-ttl:根據鍵值對象的ttl屬性,刪除最近將要過期數據。如果沒有,回退到noeviction策略。

noeviction:不會剔除任何數據,拒絕所有寫入操作並返回客戶端錯誤信息"(error)OOM command not allowed when used memory",此時Redis只響應讀操作。

 10.一個字符串類型的值能存儲最大容量是多少?

  答:512M,但是並不建議存儲bigKeys的數值,本來就是單線程的redis,如果你使用了bigKey的體積較大的數值可能造成網絡擁塞,同時也影響使用的效率,建議單個鍵值對大小不超過10kb。

11.Redis有哪些適合的場景?

  答:文章點贊模型,incr,DECR原子加減來實現,隊列操作lpush和rpop,棧的操作lpush和lpop,關注模型,使用列表的交集並集來推薦可能認識的人,購物車模型,使用哈希存儲來方面存取。

12.Jedis與Redisson對比有什麼優缺點?

  答:Jedis是連接redis最常用的插件,底層用java編寫的,對於redis的單機命令集成的非常好,但是對於一些集羣的操作不是很友好的,而Redisson也是連接我們redis的重要插件,但是集成的redis命令並不理想,可他提供了強大的分佈式鎖供我們來使用,在分佈式中,相比jedis,redisson表現的更爲出色。

13.Redis中的管道有什麼用?

  答:管道就是通過一次網絡請求,一起塞給Redis客戶端多條命令,不存在事務的控制,就是說,當我們其中的命令報錯了,並不會中斷我們管道的繼續執行,同時已經執行完的操作,也會持久化下來。

 14.談一下redis中的事務

  答:redis自身的事務並不是很好用的,一般我用Lua腳本來代替Redis的事務。用eval來執行我們的Lua腳本。

15.Redis如何做內存優化?

  答:上述提到過一些優化的方法,比如我們的鍵最好設置爲見名識意的,但是不要設置的過長,盡力的避免設置bigkey,如果真的無法避免bigkey,可以考慮水平拆分。

16.Redis分區有什麼缺點?

  答:redis集羣並不是一個強一致的集羣,通過CRC16算法分配我們的16384個卡槽上的,這時可能造成我們的一些命令失效,比如我們取得交集,並集等命令,還有我們的批量get,批量set命令。如果不在一個服務主從集羣上,會造成命令報錯。


 

最進弄了一個公衆號,小菜技術,歡迎大家的加入



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章