1. 程式人生 > >java架構之路-(Redis專題)redis面試助力滿分+

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命令。如果不在一個服務主從叢集上,會造成命令報錯。


 

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