日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一、前言

「redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件?!?/p>

Redis在緩存應用中還是很廣泛的,項目中也經常使用。基本上面試中肯定都會問到,總結一下增強記憶哈!

在享受緩存帶來的好處的同時,當然要防止這些不好的方面。

下面我們一起來看看這三種情況的產生原因和解決方案!

「總結: 這三種情況都是在大量請求來的時候,Redis沒有命中,請求直接打到數據庫,從而導致數據庫掛掉!」

Redis緩存簡圖:

看完Redis緩存穿透、緩存擊穿、緩存雪崩來吊打面試官!

二、緩存穿透

1、產生原因

「大量請求的 key 是不合理的,緩存中根本不存在(數據庫中一般也不存在),導致這些請求繞過緩存直接訪問數據庫,給數據庫造成了巨大的壓力,隨時可能宕機?!?/p>

  • 惡意查詢,如查詢id為負數等等。
  • key過期,突然來了大量請求時。
  • key沒有提前預熱,突然來了大量請求時。

2、解決方案

  • 設置緩存空值:查詢數據庫沒有結果,將空值緩存,但必須設置一個合理的過期時間。
  • 布隆過濾器:是一種用于判斷一個元素是否屬于一個集合的數據結構。
  • 合理判斷參數的范圍:非負數等等。
  • 限制并發查詢:保證只有一個線程去查詢底層數據源,其他線程等待查詢結果。

3、具體方案

「設置緩存空值:」

redis有一個配置,可以把從數據庫查詢出來為空的也緩存到Redis中,也可以自己在代碼中寫,順便加上過期時間,也可以配置過期時間,這樣是全局都是這個過期時間了,不太建議這樣!

spring:
  cache: 
    redis:
      cache-null-value: true
      time-to-live: 30s

「限制并發查詢:」

@Cacheable(value={"category"},key = "#root.methodName",sync = true)

?

sync = true:表示多個線程在嘗試獲取緩存數據的時候會被阻塞,直到第一個線程從數據庫加載數據并放入緩存后,其他線程才能獲取到緩存中的數據。這樣可以避免多個線程同時查詢底層數據庫,減輕數據庫負載,但會降低并發性能。 默認為false,不開啟

?

「布隆過濾器:」

布隆過濾器(Bloom Filter)是一種用于判斷一個元素是否屬于一個集合的數據結構。它的主要特點是高效地判斷元素是否存在于集合中,且具有空間和時間效率高的優點。布隆過濾器不會存儲實際的數據,而是通過一系列的哈希函數和位數組來判斷元素的存在。

看完Redis緩存穿透、緩存擊穿、緩存雪崩來吊打面試官!

「當布隆過濾器判斷元素不存在時,元素一定不存在,元素存在時,元素不一定存在!」

是不是有點繞,我們在詳細說一下:

布隆過濾器有一定的假陽性概率,即在判斷元素存在時,有可能出現錯誤的結果。這是因為多個元素可能產生相同的哈希值,導致位數組中的位被設置為1。

「布隆過濾器一旦添加了元素,就不能刪除,因為刪除元素會影響其他元素的判斷結果?!?/p>

一般引入guava中的BloomFilter來實現布隆過濾器!如果喜歡用Hutool,也是有實現的!

下面小編給大家簡單的寫個demo,大家感受一下!

「引入依賴」

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>

「配置布隆過濾器」

/**
 * @author wangzhenjun
 * @date 2023/11/7 17:08
 */
@Configuration
public class BloomFilterConfig {

    // 預期插入的元素個數,從配置文件里拿
    private static final Integer EXPECTED_INSERTIONS = 100000;

    // 期望的誤判率,值越低,布隆過濾器計算時間越長,從配置文件里拿
    private static final Double FPP = 0.03;

    @Bean
    public BloomFilter<String> bloomFilter(){
        BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), EXPECTED_INSERTIONS,FPP);
        return filter;
    }

}

「簡單測試」

為了簡單,直接寫在啟動類上了,大家不要學哈!

@EnableAsync
@MApperScan("com.example.demonew.demo.mapper")
@EnableTransactionManagement
@SpringBootApplication
public class DemoNewApplication {

    @Autowired
    private BloomFilter bloomFilter;

    public static void mAIn(String[] args) {
        SpringApplication.run(DemoNewApplication.class, args);

    }

    @PostConstruct
    public void init(){
        bloomFilter.put("123");
        boolean b = bloomFilter.mightContain("123");
        System.out.println("是否存在:" + b);
    }

}

看完Redis緩存穿透、緩存擊穿、緩存雪崩來吊打面試官!

三、緩存擊穿

1、產生原因

「緩存擊穿是指當緩存中某個熱點key剛剛過期(一般和緩存穿透區別在于熱點數據存在于數據庫中),在熱點數據重新放入緩存之前,瞬間大量的請求繞過緩存,直接打到數據庫,數據庫隨時宕機!」

并發訪問熱點key:多個并發請求同時訪問相同的緩存鍵

緩存策略問題:設置了過于短的緩存過期時間,容易導致緩存頻繁失效。

「一般出現在秒殺中,秒殺都會提前預熱,設置key直到活動結束才會過期!」

2、解決方案

  • 緩存預熱:系統啟動或緩存過期之前,預先加載常用數據到緩存中。
  • key永不過期或者使用期間內不過期。
  • 限制并發查詢:保證只有一個線程去查詢底層數據源,其他線程等待查詢結果。
  • 接口限流、熔斷、降級。

3、具體方案

「緩存預熱:」

在項目啟動時,或者定時任務掃描進行預熱!

「限制并發查詢:」

@Cacheable(value={"category"},key = "#root.methodName",sync = true)、

詳細解釋上面已經說過了哈!

「接口限流、熔斷、降級」

可以引入:Sentinel來幫助我們更好的限流、熔斷、降級,這里就不詳細演示了!

四、緩存雪崩

1、產生原因

「緩存雪崩是指緩存中大量key到了過期時間,導致大量的請求直接打到數據庫上,數據庫隨時宕機!」

  • redis服務宕機:redis掛了,所有的key都無法訪問
  • 批量設置大量key相同的過期時間

2、解決方案

  • redis搭建集群或者哨兵。
  • 隨機設置緩存的失效時間(合理范圍內的隨機時間),或者用不過期(不建議)。
  • 限制并發查詢:保證只有一個線程去查詢底層數據源,其他線程等待查詢結果。
  • 接口限流、熔斷、降級。
  • 多級緩存

「這個多級緩存,能不加不加,加了就需要考慮一致性,增加很多復雜度!」

其實緩存擊穿和緩存雪崩是很相似的,解決方案,大家也可以看出來很多相同的!這就引出下一個經常問到的問題:

3、具體解決方案

關于Redis的哨兵搭建可以看一下之前寫的文章,這里就不演示了!

關于多級緩存,可以引入本地緩存Caffeine。

4、補充

「緩存擊穿和緩存雪崩的區別?」

緩存擊穿是緩存中某個熱點key不存在了,緩存雪崩是緩存中大量或者所有key都不存在了

他倆的根本區別在于一個是單個key,一個是多個甚至全部key!

五、緩存污染

這里補充一下,關于緩存污染的吧!

1、產生原因

緩存污染指緩存中一些訪問次數很少的key,甚至只有一次!但是緩存中會存儲著,占用內存空間。隨著時間越來越久,內存很快被占滿,就需要開啟淘汰策略去額外處理這些多余的key,影響redis性能。

2、解決方案

  • 對與key進行監控,不常用key不需要加入緩存。
  • 分析出key訪問次數很少,設置過期時間短一些。
  • 配置淘汰策略:LRU(最近最少使用)淘汰策略。

最主要還是要把不常用的key找到,后面不在加入緩存,從根本上解決!

還會出現在多個節點之間的數據同步出現數據不統一時產生,這個東西不好避免,因為Redis 是AP(可用性和分區容忍性),在多節點時,一半以上同步完成時,就認為同步成功了!

六、緩存一致性

引入了緩存就必須要保持緩存的一致性,不然加了緩存沒有任何意義!

網上關于緩存一致性的文章很多,什么延遲雙刪等等。

這些都不如阿里Canal,這個是通過監聽MySQL的Bin Log日志,來去更新到緩存中!

七、總結

今天我們深入具體的討論了Redis緩存穿透、緩存擊穿、緩存雪崩的產生原因和解決方案,補充了緩存污染和緩存一致性。

是不是有了深刻的印象,這些東西在企業級還是挺常見的,在面試過程中更加常見。 相信大家從頭看到尾,對于面試肯定是沒有任何問題的。

在企業級應用中,一定要具體情況具體分析,不要盲目照搬,不一定適合你們的需求。

分享到:
標簽:Redis
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定