如何解決Redis緩存雪崩、擊穿與穿透
這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了關於怎麼解決redis緩存雪崩、擊穿與穿透的相關問題,緩存雪崩是指大量的請求無法命中Redis中的快取數據,也就是在Redis找不到數據了;下面一起來看一下,希望對大家有幫助。
推薦學習:Redis影片教學
#一、快取雪崩
1. 什麼是緩存雪崩?
快取雪崩
是指大量的請求無法命中Redis
中的快取數據,也就是在Redis
找不到數據了,那業務系統只能到資料庫中查詢,進而導致所有的請求都傳送到了資料庫。如下圖所示:
資料庫不像Redis
能處理大量請求,由快取雪崩導致的請求激增必須會導致資料庫所在宕機,這樣勢必會影響業務系統,所以如果發生緩存雪崩,對於業務系統肯定是致命的。
2. 為什麼發會生緩存雪崩?
什麼情況下出現快取雪崩呢?總結起來有以下兩個面向的原因:
大量
Redis
快取資料同時過期,導致所有的發送到Redis
請求都無法命中數據,只能到資料庫中進行查詢。Redis
伺服器宕機,所有請求都無法經Redis
來處理,只能轉向資料庫查詢資料。
3. 如何避免快取雪崩?
針對導致快取雪崩的原因,有不同的解決方法:
針對大量快取隨機過期時間,解決方法就是在原始過期時間的基礎上,再加上一個隨機過期時間,例如1到5分鐘之間的隨機過期時間,這樣可以避免大量的快取資料在同一時間過期。
而針對
Redis
解決當機的導致的快取雪崩,可以提前搭建好Redis
的主從伺服器進行資料同步,並配置哨兵機制,這樣在Redis
伺服器因為宕機而無法提供服務時,可以由哨兵將Redis
從伺服器設定為主伺服器,繼續提供服務。
二、快取擊穿
1. 什麼是快取擊穿
快取擊穿與快取雪崩的情況相似,雪崩是因為大量的資料過期,而快取擊穿則是指熱點資料過期,所有針對熱點資料的請求都需要到資料庫中處理,如下圖所示:
- 不設定過期時間
- 互斥鎖
Redis快取資料過期時,如果有對該資料的請求,則重新到資料庫中查詢並再寫入緩存,讓後續的請求可以命中該快取而無須再去資料庫中查詢。
Redis,也就是在寫入
Redis之前,其他要求進來,也會去查詢資料庫。
Redis,而其他沒有獲得鎖定的請求只能等待資料就緒。
#
- 設定邏輯過期時間
使用互斥鎖雖然可以非常簡單地解決快取擊穿問題,但沒有獲得鎖的請求雖然排隊等待,這樣影響了系統的效能,還有另一種解決快取擊穿的方法就是在業務資料冗餘一個過期時間,例如下面的資料中我們增加了expire_at
欄位用來表示資料過期時間。
{"name":"test","expire_at":"1599999999"}复制代码
這種方式的實作過程如下圖所示:
快取中的熱點資料中冗餘一個邏輯過期時間,但資料在Redis
不設定過期時間
當一個請求拿到Redis
中的資料時,判斷邏輯過期時間是否到期,如果沒有到期,直接傳回,如果到期則開啟另一個執行緒取得鎖定後去查詢資料庫並將查詢的最新資料寫回Redis
,而目前請求傳回已查詢的資料。
三、快取穿透
1. 什麼是快取穿透
快取穿透是指要尋找的資料既不在快取當中,也不在資料庫中,因為不在快取中,所以請求一定會到達資料庫,Redis
快取形同虛設,如下圖所示:
- 用戶惡意攻擊請求
- #錯誤操作把
Redis
和資料庫裡的數據刪除了
- 用戶還未產生內容時,例如用戶的文章列表,用戶還未寫文章,所以快取和資料庫都沒有資料
Redis快取中查詢不到資料時,再從資料庫查詢,如果同樣沒有數據,就直接快取一個空間或缺省值,這樣可以避免下次再去查詢資料庫;不過為了防止之後已經資料庫已經對應資料庫,再回傳空值問題,應該為快取設定過期時間,或是在產生資料時直接清除對應的快取空值。
布隆過濾器。
- 使用N個雜湊函數對要標記的數據進行哈希值計算。
- 將計算到的雜湊值對bit數組的長度取模,這樣就可以得到每個哈希值在bit數組的位置。
- 把bit數組中對應的位置標記為1。
Redis本身就支援布隆過濾器,所以我們可以直接使用
Redis布隆過濾器,而不用自己去實現,非常方便。
原因 | 解決方法 | |
---|---|---|
大量資料過期或 | Redis伺服器宕機 #1. 隨機過期時間 2. 主從哨兵的叢集 |
|
熱點資料過期 | 1. 不設定過期時間2. 加上互斥鎖定3.冗餘邏輯過期時間 | |
請求資料庫和 | Redis都沒有的資料 1. 快取空值或預設值2. 布隆過濾器 |
以上是如何解決Redis緩存雪崩、擊穿與穿透的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

熱門話題

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

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

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

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

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

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

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

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