目錄
#一、快取雪崩
1. 什麼是緩存雪崩?
2. 為什麼發會生緩存雪崩?
3. 如何避免快取雪崩?
二、快取擊穿
1. 什麼是快取擊穿
三、快取穿透
1. 什麼是快取穿透
首頁 資料庫 Redis 如何解決Redis緩存雪崩、擊穿與穿透

如何解決Redis緩存雪崩、擊穿與穿透

Nov 03, 2022 pm 05:23 PM
redis nosql 後端

這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了關於怎麼解決redis緩存雪崩、擊穿與穿透的相關問題,緩存雪崩是指大量的請求無法命中Redis中的快取數據,也就是在Redis找不到數據了;下面一起來看一下,希望對大家有幫助。

如何解決Redis緩存雪崩、擊穿與穿透

推薦學習:Redis影片教學

#一、快取雪崩

1. 什麼是緩存雪崩?

快取雪崩是指大量的請求無法命中Redis中的快取數據,也就是在Redis找不到數據了,那業務系統只能到資料庫中查詢,進而導致所有的請求都傳送到了資料庫。如下圖所示:

資料庫不像Redis能處理大量請求,由快取雪崩導致的請求激增必須會導致資料庫所在宕機,這樣勢必會影響業務系統,所以如果發生緩存雪崩,對於業務系統肯定是致命的。

2. 為什麼發會生緩存雪崩?

什麼情況下出現快取雪崩呢?總結起來有以下兩個面向的原因:

  • 大量Redis快取資料同時過期,導致所有的發送到Redis請求都無法命中數據,只能到資料庫中進行查詢。

  • Redis伺服器宕機,所有請求都無法經Redis來處理,只能轉向資料庫查詢資料。

3. 如何避免快取雪崩?

針對導致快取雪崩的原因,有不同的解決方法:

  • 針對大量快取隨機過期時間,解決方法就是在原始過期時間的基礎上,再加上一個隨機過期時間,例如1到5分鐘之間的隨機過期時間,這樣可以避免大量的快取資料在同一時間過期。

  • 而針對Redis解決當機的導致的快取雪崩,可以提前搭建好Redis的主從伺服器進行資料同步,並配置哨兵機制,這樣在Redis伺服器因為宕機而無法提供服務時,可以由哨兵將Redis從伺服器設定為主伺服器,繼續提供服務。

二、快取擊穿

1. 什麼是快取擊穿

快取擊穿與快取雪崩的情況相似,雪崩是因為大量的資料過期,而快取擊穿則是指熱點資料過期,所有針對熱點資料的請求都需要到資料庫中處理,如下圖所示:

##2 . 怎麼避免快取擊穿?

解決快取擊穿的三種方式:

    不設定過期時間
如果我們能事先知道某個數據是熱點數據,那麼就可以不設定這些資料的過期,從而避免快取擊穿問題,例如一些秒殺活動的商品,在秒殺時會大量用戶訪問,這時候我們就可以將這些用於秒殺的商品資料提前寫入快取並且不設定過期時間。

    互斥鎖
提前知道某些資料會有大量訪問,我們當然可以設定不過期,但更多時候,我們並不能提前預知,這種情況要怎麼處理呢?

我們來分析快取擊穿的情況:

正常情況下,當某個

Redis快取資料過期時,如果有對該資料的請求,則重新到資料庫中查詢並再寫入緩存,讓後續的請求可以命中該快取而無須再去資料庫中查詢。

而熱點資料過期時,由於大量請求,當某個請求無法命中快取時,會去查詢資料庫並重新把資料寫入

Redis,也就是在寫入Redis之前,其他要求進來,也會去查詢資料庫。

好了,我們知道熱點資料過期後,很多請求會去查詢資料庫,那麼我們可以給去查詢資料庫的業務邏輯加個互斥鎖,只有獲得鎖的請求才能去查詢資料庫並把資料寫回

Redis,而其他沒有獲得鎖定的請求只能等待資料就緒。

上述步驟的如下圖所示:

#

  • 設定邏輯過期時間

使用互斥鎖雖然可以非常簡單地解決快取擊穿問題,但沒有獲得鎖的請求雖然排隊等待,這樣影響了系統的效能,還有另一種解決快取擊穿的方法就是在業務資料冗餘一個過期時間,例如下面的資料中我們增加了expire_at欄位用來表示資料過期時間。

{"name":"test","expire_at":"1599999999"}复制代码
登入後複製

這種方式的實作過程如下圖所示:

快取中的熱點資料中冗餘一個邏輯過期時間,但資料在Redis不設定過期時間

當一個請求拿到Redis中的資料時,判斷邏輯過期時間是否到期,如果沒有到期,直接傳回,如果到期則開啟另一個執行緒取得鎖定後去查詢資料庫並將查詢的最新資料寫回Redis,而目前請求傳回已查詢的資料。

三、快取穿透

1. 什麼是快取穿透

快取穿透是指要尋找的資料既不在快取當中,也不在資料庫中,因為不在快取中,所以請求一定會到達資料庫,Redis快取形同虛設,如下圖所示:

##2. 為什麼會發生快取穿透

在什麼條件下會發生快取穿透呢?主要有以下三種情況:

  • 用戶惡意攻擊請求

  • #錯誤操作把

    Redis和資料庫裡的數據刪除了

  • 用戶還未產生內容時,例如用戶的文章列表,用戶還未寫文章,所以快取和資料庫都沒有資料

3. 如何避免快取穿透?

a. 快取空值或預設值

當在

Redis快取中查詢不到資料時,再從資料庫查詢,如果同樣沒有數據,就直接快取一個空間或缺省值,這樣可以避免下次再去查詢資料庫;不過為了防止之後已經資料庫已經對應資料庫,再回傳空值問題,應該為快取設定過期時間,或是在產生資料時直接清除對應的快取空值。

b. 布隆過濾器

雖然快取空值可以解決快取穿透問題,但仍然需要查詢一次資料庫才能確定是否有數據,如果有用戶惡意攻擊,高並發地使用系統不存在的資料id進行查詢,所有的查詢都要經過資料庫,這樣仍然會給資料庫帶來很大的壓力。

所以,有沒有不用查詢資料庫就能確定資料是否存在的辦法呢?有的,用

布隆過濾器

布林過濾器主要是兩個部分:bit數組N個雜湊函數,其原理為:

  • 使用N個雜湊函數對要標記的數據進行哈希值計算。

  • 將計算到的雜湊值對bit數組的長度取模,這樣就可以得到每個哈希值在bit數組的位置。

  • 把bit數組中對應的位置標記為1。

下面是布隆過濾器原理示意圖:

#當要進行資料寫入時,執行述述步驟,計算對應bit數組位置並標識為1,那麼執行查詢時,就能查詢該資料是否存在了。

另外,由於哈希碰撞問題導致的誤差,所以不存在的資料經過布隆過濾器後,會被判定為存在,再去查資料庫,不過哈希碰到的機率很小,用布隆過濾器已經能幫我們攔截大部分的穿透要求了。

Redis本身就支援布隆過濾器,所以我們可以直接使用Redis布隆過濾器,而不用自己去實現,非常方便。

四、小結

快取的雪崩、擊穿、穿透是在業務應用快取時經常會碰到的快取異常問題,其原因與解決方法如以下表示所示:

問題原因解決方法##快取雪崩Redis #快取擊穿快取穿透Redis推薦學習:
大量資料過期或伺服器宕機#1. 隨機過期時間 2. 主從哨兵的叢集
熱點資料過期 1. 不設定過期時間2. 加上互斥鎖定3.冗餘邏輯過期時間
請求資料庫和都沒有的資料1. 快取空值或預設值2. 布隆過濾器
Redis影片教學

#

以上是如何解決Redis緩存雪崩、擊穿與穿透的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

redis數據怎麼清空 redis數據怎麼清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

redis指令怎麼用 redis指令怎麼用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

redis怎麼使用單線程 redis怎麼使用單線程 Apr 10, 2025 pm 07:12 PM

Redis 使用單線程架構,以提供高性能、簡單性和一致性。它利用 I/O 多路復用、事件循環、非阻塞 I/O 和共享內存來提高並發性,但同時存在並發性受限、單點故障和不適合寫密集型工作負載的局限性。

redis怎麼讀源碼 redis怎麼讀源碼 Apr 10, 2025 pm 08:27 PM

理解 Redis 源碼的最佳方法是逐步進行:熟悉 Redis 基礎知識。選擇一個特定的模塊或功能作為起點。從模塊或功能的入口點開始,逐行查看代碼。通過函數調用鏈查看代碼。熟悉 Redis 使用的底層數據結構。識別 Redis 使用的算法。

redis底層怎麼實現 redis底層怎麼實現 Apr 10, 2025 pm 07:21 PM

Redis 使用哈希表存儲數據,支持字符串、列表、哈希表、集合和有序集合等數據結構。 Redis 通過快照 (RDB) 和追加只寫 (AOF) 機制持久化數據。 Redis 使用主從復制來提高數據可用性。 Redis 使用單線程事件循環處理連接和命令,保證數據原子性和一致性。 Redis 為鍵設置過期時間,並使用 lazy 刪除機制刪除過期鍵。

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

redis怎麼使用鎖 redis怎麼使用鎖 Apr 10, 2025 pm 08:39 PM

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

See all articles