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命令。如果不在一個服務主從集群上,會造成命令報錯。
最進弄了一個公眾號,小菜技術,歡迎大家的加入