亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

1. 前言

在小型項目中(例如大部分 toB 業務),Redis 被作為緩存,我們無需過多關注緩存的性能,但是對于高并發的場景(例如 toC 的在線電商業務),在商品秒殺或者庫存搶購的時候,Redis 也可能存在諸多潛在的問題,例如緩存穿透、緩存雪崩。

2. 緩存問題

2.1 緩存穿透

面試官提問: Redis 的緩存穿透是什么意思?有什么解決方案?

題目解析:

圖片描述
?

(緩存穿透圖示)

首先給出緩存穿透的定義:用戶查詢一個本來在數據庫就沒有的數據,導致每次請求要首先從緩存中查找,發現沒有之后再從持久化數據庫(例如 MySQL)中查找,最后返回空的過程。比如針對一個不存在的 user_id 查詢用戶信息,請求每次都會擊穿緩存打到數據庫上。

然后分析緩存穿透的危害:因為持久化數據庫的讀能力普遍低于緩存,緩存穿透越多,緩存命中率越低,這類請求可能被黑客利用從而打垮數據庫。

針對緩存穿透問題,業界有一些公認的解決方案:

(1)緩存空值:第一次查詢,在緩存和數據庫均查不到數據,我們將 key=user_idvalue=null 這個鍵值對放入緩存,并且設置一個短期過期時間(例如 10 分鐘);第二次以及過期時間內的查詢,流量會命中緩存,并且返回空結果。

這是最簡單粗暴的方法,如果對緩存的存儲數據有嚴格要求,一般不采用這種方案。

(2)預置布隆過濾器:布隆過濾器存儲緩存中所有的 key ,請求打進來之后,首先經過布隆過濾器過濾,如果不存在,直接在該層攔截

請求,請求流量不會打到緩存以及數據庫。如果存在,則走正常的緩存、數據庫查詢邏輯。

圖片描述

(緩存穿透解決方案)

2.2 緩存雪崩

面試官提問: Redis 的緩存雪崩是什么意思?有什么解決方案?

題目解析:

正如上文的分析,緩存的核心作用是為底層數據庫擋住大部分的外部流量,減輕數據庫的壓力。

圖片描述

(緩存雪崩圖示)

如果緩存因為某種原因失效,例如 Redis Server 宕機或者在某個時間段大量的緩存 Key 過期,原本被緩存過濾的流量會直接打到數據庫上,給數據庫造成壓力,嚴重情況下可能導致數據庫宕機。

預防緩存雪崩也有多種方案:

(1)保證 Redis 的高可用,例如搭建 Redis Cluster,維護多集群。

(2)對服務請求進行限流,例如使用 Java 的 Hystrix 庫,Hystrix 能夠提供熔斷、限流、降低三種手段保證當極端情況發生時,打到數據庫的請求流量不會超過數據庫的承受能力。

  • 熔斷:Hystrix 記錄某個接口的請求失敗率,當失敗率過高之后,拒絕后續請求,直接給出一個預設返回值;
  • 限流:當請求 QPS 超過緩存的能力或者預先計算的上限后,將后續的的請求放入緩存隊列,防止請求高并發打進業務邏輯代碼;
  • 降級:對于被拒絕訪問的請求,直接返回一個預設結果。降級最常見的應用例子是,電商秒殺的場景,當并發數超過業務服務能夠承受的閾值后,請求直接被網關層攔截,返回 "當前人數太多,請稍后重試" 的提示文案。

總結來說,預防緩存雪崩的本質方案有:

  • 加鎖:加鎖只是為了降低并發打到數據庫的流量,并沒有提高系統的吞吐量,當有 100 個用戶請求過來時,每次只能處理 1 個請求,用戶體驗差,生產環境基本不使用加鎖方案;
  • 隊列:Hystrix 限流的本質就請求放入緩存隊列,依次請求,生產環境必備方案;
  • 拒絕服務:當請求超過隊列能夠處理的范疇后,直接攔截用戶請求,用戶體驗也差,一般是生產環境的兜底方案。

3. 小結

本章節介紹了使用 Redis 作為緩存容易遇到的兩大問題,緩存穿透和緩存雪崩。需要區分的是,緩存穿透是針對單個 Key 而言,緩存雪崩是多個 Key 失效,兩者產生的原因也不同。