Redis 三大緩存


Redis 三大緩存

     過去的有些事情不一定要忘記,但一定要放下。

 

背景:Redis 三大緩存:緩存穿透、緩存擊穿、緩存雪崩,是Redis 面試必須要掌握的東西。

一、緩存穿透

1.概念簡述

緩存穿透是指當用戶在查詢一條數據時,而此時數據庫緩存卻沒有關於這條數據的任何記錄;而該數據若在緩存中沒找到則會向數據庫請求獲取數據,Redis 拿不到數據時,就會一直查詢數據庫,這樣會對數據庫的訪問造成很大的壓力。

2.案例

用戶查詢一個 id = -1 的商品信息,但是數據庫 id 自增是從 1 開始的,很明顯這條信息是不在數據庫中,當沒有信息返回時,Redis 會一直向數據庫查詢,給當前數據庫訪問造成很大的壓力。

3.解決方案

A、從緩存出發,給緩存設置一個 如果當前數據庫不存在 的信息,把它緩存為一個空對象,返回給用戶;

B、緩存空對象的解決方案代碼簡單,但效果不是很好;可以考慮使用Redis 提供的布隆過濾器。

Redis 布隆過濾器代碼:

 1 package com.ausclouds.bdbsec.tjt;  2 
 3 import com.google.common.hash.BloomFilter;  4 import com.google.common.hash.Funnels;  5 
 6 import java.nio.charset.Charset;  7 
 8 /**
 9  * Redis 布隆過濾器 10  * 引入依賴: 11  * <dependency> 12  * <groupId>com.google.guava</groupId> 13  * <artifactId>guava</artifactId> 14  * <version>22.0</version> 15  * </dependency> 16  */
17 public class BloomFilterDemon { 18 
19     // initial_size: 表示預計放入的元素數量,當實際數量超出這個數值時,誤判率會上升
20     private static long initial_size = 1000000; 21 
22     // error_rate: 錯誤率
23     private static double error_rate = 0.0001; 24 
25     public static void main(String[] args) { 26         BloomFilter<String> bloomFilter =
27  BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), initial_size, error_rate); 28         bloomFilter.put("what"); 29         boolean isContain = bloomFilter.mightContain("what"); 30 
31  } 32 
33 
34 }
View Code~拍一拍小輪胎

 緩存空對象流程圖

二、緩存擊穿

1.概念簡述

緩存擊穿是指有某個key 經常被查詢,或者某個key 不經常被訪問,而這個時候,若該key 在緩存的過期時間失效或者是個冷門key 的時候,突然有大量關於這個key 的訪問請求,這樣就會導致大並發請求直接穿透緩存,請求數據庫,瞬間增大了數據庫的訪問壓力。

2.案例

(1)一個“冷門”key,突然被大量用戶請求訪問;

(2)一個“熱門”key,在緩存中時間恰好過期,這時有大量用戶來進行訪問。

緩存擊穿案例圖

3.解決方案

對於緩存擊穿問題,常用的解決方案是加鎖;對於key 過期問題,當key 要查詢數據庫的時候加上鎖,保證只能讓第一個請求進行查詢數據庫操作,然后把從數據庫中查詢到的值存儲到緩存中,對於剩下的相同的key,則可直接從緩存中獲取。

緩存擊穿解決方案圖

三、緩存雪崩

1.概念簡述

緩存雪崩是指在某一個時間段內,緩存集中過期失效,若這個時間段內有大量請求,並且查詢數據量巨大,所有的請求都會查詢數據庫,使數據庫的調用瞬間量劇增,引起數據庫壓力過大甚至宕機。(Redis 突然宕機或大部分數據失效)

2.案例

某寶雙十一購物節,在 23:00-24:00 舉行商品促銷活動。開發人員是這么設計的:在 23:00 把商家促銷的商品放到緩存中,並通過redis 的expire 設置了過期時間為1小時;這個時間段許多用戶在訪問這些商品信息,但是剛好到了24:00點的時候,恰好還有許多用戶在訪問這些商品,此時對這些商品的訪問都會轉到數據庫上,導致數據庫壓力突然劇增,甚至直接宕機。

3.解決方案

A、限流降級

在緩存失效后,通過加鎖或者隊列來控制讀數據庫寫緩存和寫緩存的線程數量,對某個key 同一時刻只允許一個線程執行查詢設計和寫緩存操作。

B、Redis 高可用

可能會出現Redis 掛掉的情況,多增加幾台Redis 實例(一主多從),即使一台掛掉之后其他的還可以繼續工作。

C、不同過期時間

設置不同的過期時間,讓緩存失效的時間盡量均勻,避免同一時間大量緩存失效。

D、數據預加熱

數據加熱的含義就是在正式部署之前,先把可能用到的數據預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中;一般可以在即將發生大並發訪問前手動觸發加載緩存不同的key。

 

 

過去的有些事情不一定要忘記

但一定要放下

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM