原文:
談談使用redis快取時批量刪除的幾種實現
在使用快取的時候,我們時不時會遇到這樣乙個需求,根據快取鍵的規則去批量刪除這些資料,比較常見的就是按字首去刪除。
舉個簡單的例子,redis中現在有幾百個商品的資料,這些資料的key值是有一定規律的,都是以product:id
的形式存在的。
現在由於不得以為的原因要刪除這幾百個商品的資料,這個時候我們肯定就要把快取鍵以product:
開頭的給全部刪除掉。
其實這個需求在redis中是可以很容易去實現的。
來看看幾種常見的做法。
用keys命令找到key之後執行刪除操作
用scan命令找到key之後執行刪除操作(2.8.0版本之後)
新增快取資料的時候,可以同時將key存放到乙個set中,然後依據這個set來執行刪除操作
對於keys命令,網上有不少血的教訓,對於生產環境還是要謹慎謹慎再謹慎!能不用就別用。
scan命令的話是大部分人推薦的做法,是增量式迭代的乙個命令。
存到set中就相對繁瑣一點,而且額外占用了一部分記憶體。而且在進行刪除的時候還要從這裡讀取出相應的key,同時也要移除這部分key的資料。
下面來看看如何在.net core中來處理,主要還是針對scan的做法。
示例操作redis用的是stackexchange.redis。
可能有人會有疑惑,不是說keys命令盡量不要用嗎?怎麼你還用?
這個還真的要解釋一下!
可能從方法上,我們找遍所有iserver和idatabase介面都找不到純粹的scan命令(setscan,hashscan等除外)。
但是如果看過裡面的實現,你就會知道是為什麼了!
傳送門:keys
可以看看下圖高亮的兩行**:
大致意思就是,如果你用的redis的版本支援scan命令,走的就是scan,反之只能是keys了。
下面定義乙個查詢rediskey的方法。
private static rediskey searchrediskeys(iserver server, string pattern)
",keys.length);
return keys;
}
知道那些key要刪除,剩下的就比較簡單了!
private static void keysorscansolution(iserver server,idatabase db, string pattern)
iserver.keys可以說是隱式的呼叫了scan命令,那麼我們自然也可以顯式的去呼叫這個命令來完成這些。
private static rediskey searchrediskeys(idatabase db,string pattern)
while (nextcursor != 0);
return keys.toarray();
}
刪除的**。
private static void executesolution(idatabase db, string pattern)
當然還有一種做法是呼叫lua指令碼去完成,這裡就不細說了。
雖然上面幾種做法能比較簡單的處理這個問題,但是在拿出這些keys的時候,客戶端的記憶體占用可能會比較大,尤其是有大量符合條件的快取項的時候。
涉及快取的諸多操作(包含根據字首去刪除快取項),我也在easycaching中實現了相應的操作,後面也會不斷的抽時間來完善這一專案,有興趣的朋友可以關注一下。
文中的示例** redisbatchremovesolution
請你談談Redis快取穿透和雪崩?
redis快取的使用,極大的提公升了應用程式的效能和效率,特別是資料查詢方面。但同時,它也帶來了一 些問題。其中,最要害的問題,就是資料的一致性問題,從嚴格意義上講,這個問題無解。如果對資料的一致性要求很高,那麼就不能使用快取。另外的一些典型問題就是,快取穿透 快取雪崩和快取擊穿。目前,業界也都有比...
redis快取使用
compile group org.springframework.boot name spring boot starter data redis version 2.3.2.release spring 主要引數 redis host localhost port 6379 passport 預...
快取Redis使用
在 redis 中有五種資料型別 redis 內部使用乙個 redisobject 物件來表示所有的 key 和 value。redis 記憶體淘汰指的是使用者儲存的一些鍵被可以被 redis 主動地從例項中刪除,從而產生讀 miss 的情況,那麼 redis 為什麼要有這種功能?這就是我們需要 的...