redis的常見用法和問題之緩存擊穿、緩存穿透、緩存雪崩詳解
本文為總結(jié)用于復(fù)習(xí)和查詢
包含redis的常用操作和緩存相關(guān)問題
Redis定義
Redis存儲的是key-value結(jié)構(gòu)的數(shù)據(jù),key生成字符串類型。
Redis的value的常用數(shù)據(jù)類型
字符串string

哈希hash:類似于java中的HashMap結(jié)構(gòu)

列表list:按照插入順序排序,可以有重復(fù)元素,類似java中的LinkedList

集合set:無序集合,沒有重復(fù)元素,類似java中的HashSet

有序集合sorted set / zset:集合中每個元素關(guān)聯(lián)一個score,根據(jù)score升序排列,沒有重復(fù)元素。

Redis常用命令
通用命令
- keys pattern 查找所有符合給定模式pattern的key
- exists key 檢查給定的key是否存在(返回1表示鍵存在,返回0表示鍵不存在)
- type key 返回指定key所存儲的值的類型
- del key 用于在key存在是刪除key
字符串操作命令
- set key value 設(shè)置指定key的值為value
- get key 獲取指定key的值
- setex key seconds value 設(shè)置指定key的值,并將key的過期時間設(shè)置為seconds秒
- setnx key value 只有在key不存在時設(shè)置key的值
哈希操作命令
- hset key field value 將哈希表key中的字段field設(shè)為value
- hget key field 獲取存儲在哈希表key中的field字段的值
- hdel key field 刪除存儲在哈希表中的指定字段
- hkeys key 獲取哈希表key中的所有字段
- hvals key 獲取哈希表key中所有值
列表操作命令
- lpush/rpush key value1 [value2] 將一個或多個值插入到列表的頭部/尾部
- lpop/rpop key 移除并獲取列表頭部/尾部元素
- lrange key start stop 獲取列表指定范圍內(nèi)的元素
- start:區(qū)間起始位置(從 0 開始計數(shù))。支持負(fù)數(shù),表示從列表末尾倒數(shù)(例如 -1 表示最后一個元素)。
- stop:區(qū)間結(jié)束位置(包含在內(nèi))。同樣支持負(fù)數(shù)。
- lrange mylist 0 -1 返回所有元素,等同于
- llen key 獲取列表的長度
- lindex key index 用于獲取列表key中指定索引位置index的元素
- lrem key count value 用于從列表key中移除元素的命令。該命令根據(jù)指定的值和數(shù)量,從列表的頭部或尾部開始移除匹配的元素。
count:移除元素的數(shù)量,具體含義如下:
- count > 0:從列表頭部開始,移除最多count個與value相等的元素。
- count < 0:從列表尾部開始,移除最多count的絕對值個與value相等的元素。
- count = 0:移除列表中所有與value相等的元素。
value:要移除的元素值。
集合操作命令
- sadd key member1 [member2] 向集合key添加一個或多個成員
- smembers key 獲取集合key中的所有成員
- scard key 獲取集合key中的成員的數(shù)量
- sinter key1 [key2] 返回給定所有集合的交集
- sunion key1 [key2] 返回給定所有集合的并集
- srem key member1 [member2] 刪除集合key中的一個或多個成員
有序集合操作命令
- zadd key score 1 member1 [score2 member2] 向有序集合添加一個或多個成員
- zrange key start stop [withscores] 返回指定區(qū)間的成員,加上withscores顯示成員對應(yīng)的score
- zincrby key increment member 給有序集合key中指定成員的分?jǐn)?shù)加increment
- zrem key member1 [member2…] 移除有序集合中的一個或多個成員
緩存穿透問題解決方案
什么是緩存穿透:指客戶端請求的數(shù)據(jù)在緩存redis中和數(shù)據(jù)庫中都不存在,導(dǎo)致大量請求到數(shù)據(jù)庫,從而導(dǎo)致數(shù)據(jù)庫壓力驟增
解決方案
緩存空對象:對數(shù)據(jù)庫查詢結(jié)果為空的請求,返回空值,并緩存null到redis且設(shè)置ttl,即key:null
需設(shè)置好ttl,避免長期占用內(nèi)存
布隆過濾器:在緩存之前加一層布隆過濾器,預(yù)先將數(shù)據(jù)庫中所有存在的 key 加載到布隆過濾器中。
什么是布隆過濾器過濾器:布隆過濾器是一種空間效率極高的概率型數(shù)據(jù)結(jié)構(gòu),用于判斷一個元素是否存在于一個集合中。
核心特點:
高效省空間:相比哈希表,它用位數(shù)組 + 多個哈希函數(shù)實現(xiàn),占用內(nèi)存極小,適合海量數(shù)據(jù)場景。
概率性結(jié)果:
不存在則一定不存在(100% 準(zhǔn)確);
存在則可能存在(有一定誤判率,無法完全避免)。
不支持刪除:元素加入后無法移除,否則會影響其他元素的判斷(部分變種支持刪除,但復(fù)雜度高)。
工作原理:
初始化一個長度為 m 的位數(shù)組,所有位初始化為 0;
選取 k 個獨立的哈希函數(shù);
添加元素:將元素通過 k 個哈希函數(shù)計算出 k 個索引,把位數(shù)組對應(yīng)索引的位設(shè)為 1;
查詢元素:將元素通過 k 個哈希函數(shù)計算索引,若所有對應(yīng)位都是 1,則判斷 “可能存在”;只要有一個位是 0,則判斷 “一定不存在”。
攔截流程:
客戶端發(fā)起請求,先經(jīng)過布隆過濾器判斷 key 是否存在; 若布隆過濾器判斷 key 不存在 → 直接返回空結(jié)果,不訪問緩存和數(shù)據(jù)庫; 若布隆過濾器判斷 key 可能存在 → 再走正常流程:查緩存 → 緩存未命中查數(shù)據(jù)庫 → 數(shù)據(jù)庫查到則回寫緩存。
使用布隆過濾器的注意事項:
- 誤判率處理:
布隆過濾器的誤判會導(dǎo)致 “不存在的 key 被判斷為可能存在”,此時請求仍會打到數(shù)據(jù)庫,但這種情況概率低,且可以通過調(diào)整位數(shù)組長度 len 和哈希函數(shù)個數(shù) k 降低誤判率(len越大、k 適中,誤判率越低)。 - 數(shù)據(jù)同步:
當(dāng)數(shù)據(jù)庫中新增 / 刪除 key 時,需要同步更新布隆過濾器(刪除操作需注意布隆過濾器不支持直接刪除的問題,可通過定時重建布隆過濾器解決)。 - 適用場景:
適合海量數(shù)據(jù)、key 不常變動、可以容忍低誤判率的場景(如:電商商品 ID、用戶 ID 過濾)。
緩存擊穿問題解決方案
什么是緩存擊穿:指高并發(fā)場景下,某個熱點數(shù)據(jù)的緩存突然失效(例如過期),導(dǎo)致大量請求直接穿透緩存層,直接請求到數(shù)據(jù)庫,可能導(dǎo)致數(shù)據(jù)庫短時間內(nèi)承受巨大的壓力。
解決方案:
- 互斥鎖:當(dāng)緩存失效時,只允許一個線程去查詢數(shù)據(jù)庫并重建緩存,其他線程等待??梢允褂梅植际芥i(如Redis的setnx)實現(xiàn)互斥。

- 優(yōu)點:沒有額外的內(nèi)存消耗;保證了一致性;實現(xiàn)簡單;
- 缺點:線程需要等待;可能死鎖
- 邏輯過期:為熱點數(shù)據(jù)設(shè)置邏輯過期時間,而非物理過期。緩存本身不主動失效,但在緩存中存儲一個過期時間字段。當(dāng)發(fā)現(xiàn)數(shù)據(jù)過期時,異步觸發(fā)緩存更新。

- 優(yōu)點:線程無需等待,性能較好
- 缺點:不能保證一致性;有額外的內(nèi)存消耗;實現(xiàn)較復(fù)雜
緩存雪崩問題解決方案
什么是緩存雪崩:指緩存系統(tǒng)在某一時刻出現(xiàn)大規(guī)模失效或宕機(jī),導(dǎo)致大量請求直接涌向數(shù)據(jù)庫,引發(fā)系統(tǒng)性能急劇下降甚至崩潰的現(xiàn)象。
解決方案:
- 給不同的key的ttl設(shè)置隨機(jī)值
- 部署 Redis 集群或哨兵模式,確保單點故障時自動切換
- 給業(yè)務(wù)添加多級緩存
- 給緩存業(yè)務(wù)添加降級限流策略
BitMap
什么是BitMap:Bitmap是Redis中一種特殊的數(shù)據(jù)結(jié)構(gòu),基于字符串類型實現(xiàn),但每個位可以單獨操作。適用于需要高效存儲和操作大量布爾值的場景。最大上限是512M,轉(zhuǎn)換成bit是2^32個bit位
BitMap的常見用法
- setbit key offet value 向指定位置offet存入一個0或1
- getbit key offet 獲取指定位置offet的bit值
- bitcount key [start end] 統(tǒng)計指定范圍內(nèi)bit為1的數(shù)量
- bitpos key bit [start] [end] 查詢指定范圍內(nèi)第一個0或1出現(xiàn)的二進(jìn)制位的位置
總結(jié)
到此這篇關(guān)于redis的常見用法和問題之緩存擊穿、緩存穿透、緩存雪崩的文章就介紹到這了,更多相關(guān)redis緩存擊穿、緩存穿透、緩存雪崩內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot項目redis緩存異常實戰(zhàn)案例詳解(提供解決方案)
redis基本上是高并發(fā)場景上會用到的一個高性能的key-value數(shù)據(jù)庫,屬于nosql類型,一般用作于緩存,一般是結(jié)合數(shù)據(jù)庫一塊使用的,但是在使用的過程中可能會出現(xiàn)異常的問題,這篇文章主要介紹了springboot項目redis緩存異常實戰(zhàn)案例詳解(提供解決方案),需要的朋友可以參考下2025-05-05
Redis中Stream詳解及應(yīng)用小結(jié)
Redis Streams是Redis 5.0引入的新功能,提供了一種類似于傳統(tǒng)消息隊列的機(jī)制,但具有更高的靈活性和可擴(kuò)展性,本文給大家介紹Redis中Stream詳解及應(yīng)用小結(jié),感興趣的朋友一起看看吧2025-07-07
使用Redis控制表單重復(fù)提交和控制接口訪問頻率方式
這篇文章主要介紹了使用Redis控制表單重復(fù)提交和控制接口訪問頻率方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
Redis+Caffeine如何構(gòu)建高性能二級緩存
這篇文章主要介紹了Redis+Caffeine如何構(gòu)建高性能二級緩存問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
redis 實現(xiàn)登陸次數(shù)限制的思路詳解
這篇文章主要介紹了redis 實現(xiàn)登陸次數(shù)限制的思路詳解,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
Redis源碼與設(shè)計剖析之網(wǎng)絡(luò)連接庫
這篇文章主要為大家介紹了Redis源碼與設(shè)計剖析之網(wǎng)絡(luò)連接庫詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

