Redis基礎

目錄

Redis的數據結構

Redis的過期策略

Redis持久化

RDB(快照):

AOF:

緩存雪崩

緩存穿透

緩存擊穿

主從同步


 


Redis的數據結構

String

字符串,內存中以字節數組的形式存在。

Redis 規定字符串的長度不得超過 512M 字節

List:

列表:相當於LinkedList 是鏈表結構不是數組

常用於異步隊列使用。將需要延後處理的任務結構體序列化成字符串塞進 Redis 的列表,另一個線程從這個列表中輪詢數據進行處理

hash (字典)

1. 結構相當於HashMap(數組加鏈表的結構)

2.因爲 Java 的 HashMap 在字典很大時,rehash 是個耗時的操作,需要一次性全部 rehash。Redis 爲了高性能,不能堵塞服務,所以採用了漸進式 rehash 策略。

3.漸進式 rehash 會在 rehash 的同時,保留新舊兩個 hash 結構,查詢時會同時查詢兩個 hash 結構,然後在後續的定時任務中以及 hash 操作指令中,循序漸進地將舊 hash 的內容一點點遷移到新的 hash 結構中。當搬遷完成了,就會使用新的hash結構取而代之。

set (集合)

1.相當於java中的hashSet,它內部的鍵值對是無序的唯一的。它的內部實現相當於一個特殊的字典,字典中所有的 value 都是一個值NULL

2.set 結構可以用來存儲活動中獎的用戶 ID,因爲有去重功能,可以保證同一個用戶不會中獎兩次。

zset (有序集合)

1.Java 的 SortedSet 和 HashMap 的結合體,一方面它是一個 set,保證了內部 value 的唯一性,另一方面它可以給每個 value 賦予一個 score,代表這個 value 的排序權重。它的內部實現用的是一種叫做「跳躍列表」的數據結構。

Redis的過期策略

注意:需要注意的是過期是以對象爲單位,比如一個 hash 結構的過期是整個 hash 對象的過期,而不是其中的某個子 key

惰性刪除策略:在客戶端訪問這個 key 的時候,redis 對 key 的過期時間進行檢查,如果過期了就立即刪除

定時掃描策略:Redis 默認會每秒進行十次過期掃描,過期掃描不會遍歷過期字典中所有的key,而是採用了一種簡單的貪心策略。

  1. 從過期字典中隨機 20 個 key;
  2. 刪除這 20 個 key 中已經過期的 key;
  3. 如果過期的 key 比率超過 1/4,那就重複步驟 1;

爲了保證過期掃描不會出現循環過度,導致線程卡死現象,算法還增加了掃描時間的上限,默認不會超過 25ms。

理解:定時掃描是隨機抽取的,會導致很多過期的Key沒被刪除,此時就需要靠惰性刪除

但是還是有問題啊? 要是定時沒被掃描到,我也不去查,也不走惰性刪除,那不是會有漏網之魚嗎,如果大量過期key堆積在內存裏,導致redis內存塊耗盡了,怎麼辦?

 答案是:走內存淘汰機制。

 

Redis持久化

RDB(快照):

快照是一次全量備份,快照是內存數據的二進制序列化形式,在存儲上非常緊湊

實現原理:Redis 使用操作系統的多進程 COW(Copy On Write) 機制來實現快照持久化。

Redis 在持久化時會調用 glibc 的函數fork產生一個子進程,快照持久化完全交給子進程來處理,父進程繼續處理客戶端請求。子進程剛剛產生時,它和父進程共享內存裏面的代碼段和數據段

優點

  RDB對Redis的性能影響非常小,是因爲在同步數據的時候他只是fork了一個子進程去做持久化的,而且他在數據恢復的時候速度比AOF來的快

缺點:

RDB都是快照文件,都是默認五分鐘甚至更久的時間纔會生成一次,這意味着你這次同步到下次同步這中間五分鐘的數據都很可能全部丟失掉。AOF則最多丟一秒的數據,數據完整性上高下立判

AOF:

AOF 日誌存儲的是 Redis 服務器的順序指令序列,AOF 日誌只記錄對內存進行修改的指令記錄

一樣的數據,AOF文件比RDB還要大

那麼我們該怎麼選擇兩種持久化方式呢?

 你單獨用RDB你會丟失很多數據,你單獨用AOF,你數據恢復沒RDB來的快,真出什麼時候第一時間用RDB恢復,然後AOF做數據補全,真香!冷備熱備一起上,纔是互聯網時代一個高健壯性系統的王道

  

 

緩存雪崩

      指的是在一個時間段內,緩存大量的一起失效。

      比如馬上就要到雙十二零點,很快就會迎來一波搶購,這波商品時間比較集中的放入了緩存,假設緩存一個小時。那麼到了凌晨一點鐘的時候,這批商品的緩存就都過期了。而對這批商品的訪問查詢,都落到了數據庫上,對於數據庫而言,就會產生週期性的壓力波峯。

     解決方案:

      1.避免緩存設置相近的有效期;爲有效期增加隨機值;統一規劃有效期,失效時間均勻分佈。

      2.設置熱點數據永遠不過期,有更新操作就更新緩存就好了(比如運維更新了首頁商品,那你刷下緩存就完事了,不要設置過期時間),電商首頁的數據也可以用這個操作,保險

    舉個例子,商品的分類啊可以做不同的緩存時間,並且相同類別的商品可以給緩存時間加上隨機值,這樣避免在同一個時間緩存大面積失效

    

 

緩存穿透

   指的是 數據庫和緩存中都沒有數據(比如用id =-1去請求,但是數據庫裏的id全部都是大於0的),然後你去請求,必然都打到數據庫上,每次都這樣,併發高點就容易崩掉了。

解決方案:接口層增加校驗,比如用戶鑑權校驗,參數做校驗,不合法的參數直接代碼Return,比如:id 做基礎校驗,id <=0的直接攔截等。

 

緩存擊穿

   是指一個Key非常熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個Key在失效的瞬間,持續的大併發就穿破緩存,直接請求數據庫,就像在一個完好無損的桶上鑿開了一個洞。

解決方案:設置熱點數據永遠不過期。或者加上互斥鎖就能搞定了

 

主從同步

  你啓動一臺slave 的時候,他會發送一個psync命令給master ,如果是這個slave第一次連接到master,他會觸發一個全量複製。master就會啓動一個線程,生成RDB快照,還會把新的寫請求都緩存在內存中,RDB文件生成後,master會將這個RDB發送給slave的,slave拿到之後做的第一件事情就是寫進本地的磁盤,然後加載進內存,然後master會把內存裏面緩存的那些新命名都發給slave。

參考資料:https://blog.csdn.net/weixin_42711549/article/details/83061052

 

發佈了34 篇原創文章 · 獲贊 35 · 訪問量 9145
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章