天天看點

Redis基本資料結構以及雪崩、穿透、擊穿等

Redis有哪些資料結構?

字元串Sting 、 字典Hash、 清單List、 集合Set、 有序集合SortedSet。此外還有HyperLogLog、 Geo、 Publ/Sub

Redis分布式鎖

先拿setnx争搶鎖,搶到之後,再用expire給鎖加一個過期時間防止鎖忘記釋放。

如果在setnx之後執行expire之前程序意外crash或者要重新開機那會怎麼樣?

set指令可以同時把setnx和expire合成一條指令來用

如果這個redis正在給線上的業務提供服務,那使用keys指令會有什麼問題?

redis是單線程的,keys指令會導緻線程阻塞一段時間,線上的服務會停頓,直到指令執行完畢,服務才能恢複。這個時候可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key清單,但是會有一定的重複率,整體花費的時間比直接使用keys指令長。

scan指令

SCAN指令的有SCAN,SSCAN,HSCAN,ZSCAN。

SCAN的話就是周遊所有的keys

其他的SCAN指令的話是SCAN選中的集合。

SCAN指令是增量的循環,每次調用隻會傳回一小部分的元素。是以不會有KEYS指令的坑。

SCAN指令傳回的是一個遊标,從0開始周遊,到0結束周遊。

scan指令就是對這個一維數組進行周遊。每次傳回的遊标值也都是這個數組的索引。limit參數表示周遊多少個數組的元素,将這些元素下挂接的符合條件的結果都傳回。因為每個元素下挂接的連結清單大小不同,是以每次傳回的結果數量也就不同

Redis做異步隊列

使用redis做異步隊列,正常使用list結構作為隊列,rpush生産消息,lpop消費消息,當lpop沒有消息的時候,要适當sleep一會再重試。在不采用sleep時候,list還有指令叫blpop,在沒有消息的時候,它會阻塞住直到消息到來。生産的任務使用pub/sub主題訂閱者模式,就可以實作1:N的消息隊列

redis如何實作延時隊列?

使用sortedset,拿時間戳作為score,消息内容作為key調用zadd來生産消息,消費者用zrangebyscore指令擷取N秒之前的資料輪詢進行處理

redis持久化的幾種方式

redis提供兩種方式進行持久化,一種是RDB持久化(原理是将redis在記憶體中的資料庫記錄定時dump到磁盤上的RDB持久化),另外一種是AOF持久化(原理是将redis的記錄檔以追加的方式寫入檔案)

RDB持久化是指在指定的時間間隔内将記憶體中的資料集快照寫入磁盤,實際操作過程是fork一個子程序,先将資料集寫入臨時檔案,導入成功後,再替換之前的檔案,用二進制壓縮存儲。

AOF持久化以日志的形式記錄伺服器所處理的每一個寫、删除操作,查詢操作不會記錄,以文本的方式記錄,可以打開檔案看到詳細的操作記錄。

比較:

1、aof檔案比rdb更新頻率高,優先使用aof還原資料。

2、aof比rdb更安全也更大

3、rdb性能比aof好

4、如果兩個都配了優先加載AOF

當突然機器掉電,資料是否完整?如果不完整會丢失多少資料

丢失的資料取決于AOF日志sync屬性的配置,如果不要求性能,在每條寫指令都sync一下磁盤,就不會丢失資料,但在高性能的要求下,一般都是定時,最多會丢失1s資料

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

緩存穿透:一般的緩存系統按照key去緩存查詢,如果不存在key對應的value,就會去資料庫查詢,當有一些惡意的請求故意查詢不存在的key,請求量很大,就會對後端系統造成很大的壓力。

如何避免? 1、對查詢為空的情況也進行緩存,緩存時間設定短一點,或者key對應的資料insert之後清理記憶體 2、對一定不存在的key進行過濾,可以使用布隆過濾器,将在查詢範圍外的key進行過濾

緩存雪崩:當伺服器重新開機或者大量緩存集中在某一個時間段失效,這樣在失效的時候會給後端帶來很大的壓力,導緻系統崩潰。

如何避免? 1、在緩存失效後,通過加鎖或者隊列來控制讀資料庫寫緩存的線程數量。比如某個key隻允許一個線程查詢資料和寫緩存,其他線程等待。 2、做二級緩存,A1為原始緩存,A2為拷貝緩存,A1失效時,可以通路A2,A1失效時間設定短期,A2設定為長期 3、不同的key,設定不同的過期時間,讓緩存失效時間點盡量均勻。

緩存擊穿: 緩存擊穿指的是緩存中沒有,但是資料庫存在的資料,當這個熱點資料到期,該熱點資料請求的使用者并發量特别大,導緻都穿過redis直接請求資料庫,造成資料庫壓力增大。

如何避免? 1、設定熱點資料永不過期 2、接口限流。在重要的接口我們都必須做好限流,防止惡意使用者刷接口。3、使用互斥鎖,常用的做法使用mutex。就是在緩存失效的時候,不立即去請求資料庫,而是使用緩存工具的某些成功操作傳回值的操作,比如redis的setnx 去set一個mutex key,當操作傳回成功時候,再進行load db的操作回設緩存。

繼續閱讀