Redis中緩存預熱與緩存穿透解決方案
一、簡介
1.1 簡介
Redis是一個用于數(shù)據(jù)緩存、消息代理、持久化存儲的內存型數(shù)據(jù)庫。Redis的特點是高性能、高并發(fā)、支持豐富的數(shù)據(jù)類型,可以實現(xiàn)多種應用場景。
1.2 緩存預熱 穿透
緩存預熱是在系統(tǒng)開始運行之前,將數(shù)據(jù)加入緩存中。這樣在后續(xù)的請求中,可以直接從緩存中讀取數(shù)據(jù),提高了系統(tǒng)的性能和響應速度。
緩存穿透是指查詢一個不存在的數(shù)據(jù),這會導致大量請求直接打到數(shù)據(jù)庫上,影響數(shù)據(jù)庫的性能。緩存穿透可以通過在緩存層增加布隆過濾器等進行解決。
二、緩存預熱
2.1 緩存預熱基本原理
緩存預熱的基本原理:程序啟動或重啟的時候,將需要經常訪問的數(shù)據(jù),提前加載到緩存當中,以便后續(xù)直接讀取。
2.2 Redis 緩存預熱實現(xiàn)
2.2.1 基于數(shù)據(jù)量預熱
根據(jù)數(shù)據(jù)量的大小進行預熱,比較常見的方法是在程序啟動時,讀取所有的數(shù)據(jù),將數(shù)據(jù)全部寫入緩存當中,以此實現(xiàn)緩存預熱。其優(yōu)點是預熱完成后,可以避免緩存穿透;缺點是數(shù)據(jù)量大的時候,預熱的時間較長。
2.2.2 基于時間預熱
根據(jù)數(shù)據(jù)最近的更新時間和訪問頻率,對數(shù)據(jù)進行預熱。比如最近7天讀取頻率比較高的數(shù)據(jù),在程序啟動時就可以進行預熱。其優(yōu)點是可以提高預熱效率;缺點是無法避免緩存穿透。
2.2.3 周期性預熱
周期性預熱是指定期間內進行緩存預熱,以保證系統(tǒng)的高效性。比如每天凌晨1點進行緩存預熱,以此保證當系統(tǒng)高峰期到來時,能夠有足夠的緩存支持。其優(yōu)點是預熱時間可控,缺點是可能不能覆蓋到所有的數(shù)據(jù)。
public class RedisCachePreheating { /** * 緩存預熱:基于數(shù)據(jù)量預熱 */ public void preheatByDataSize(){ // 讀取所有數(shù)據(jù) List<Data> dataList = readAllData(); for(Data data : dataList){ // 將數(shù)據(jù)寫入緩存 writeToCache(data); } } /** * 緩存預熱:基于時間預熱 */ public void preheatByTime(){ // 獲取最近7天的數(shù)據(jù)列表 List<Data> dataList = readDataByTime(7); for(Data data : dataList){ // 將數(shù)據(jù)寫入緩存 writeToCache(data); } } /** * 緩存預熱:周期性預熱 */ public void periodPreheat(){ // 每隔1小時預熱一次 Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // 預熱操作,類似于preheatByDataSize()或preheatByTime() } }, 0, 60 * 60 * 1000); } }
三、緩存穿透
3.1 緩存穿透基本原理
緩存穿透是指當一個查詢不存在于緩存中,而且每次查詢也都不會被緩存時,就會直接訪問數(shù)據(jù)庫。如果出現(xiàn)大量查詢結果不存在的情況,就可能導致數(shù)據(jù)庫崩潰。緩存穿透的原因可能是因為查詢的條件非常特殊或者惡意攻擊。
3.2 Redis 緩存穿透解決方案
以下是常見的 Redis 緩存穿透解決方案:
3.2.1 布隆過濾器
布隆過濾器是一種內存型、不可逆的數(shù)據(jù)結構。它使用哈希函數(shù)來判斷一個元素是否在集合中。因為它的計算量小且運行速度快,所以通常被用作解決緩存穿透和大數(shù)據(jù)去重等問題。
在 Redis 中,我們可以使用 RedisBloom 模塊來實現(xiàn)布隆過濾器。
Java 實現(xiàn)布隆過濾器的代碼示例:
// 創(chuàng)建布隆過濾器并將其添加到 Redis 中 Jedis jedis = new Jedis("localhost", 6379); RedisBloomFilter<Integer> bloomFilter = RedisBloomFilter.create(jedis, "bloom", 1000, 0.01); bloomFilter.add(42); // 檢查元素是否存在于集合中 bloomFilter.contains(42); // 返回 true bloomFilter.contains(666); // 返回 false
3.2.2 緩存空對象
當緩存查詢結果為空時,我們可以將這個空對象添加到緩存中。這樣下次同樣的查詢就會命中緩存,而不用去訪問數(shù)據(jù)庫了。
Java 實現(xiàn)緩存空對象的代碼示例:
// 查詢緩存。 Object result = redisTemplate.opsForValue().get(key); if(result == null) { // 查詢數(shù)據(jù)庫。 result = dao.query(key); // 將查詢結果添加到緩存,有效期設置為 5 分鐘。 redisTemplate.opsForValue().set(key, result, Duration.ofMinutes(5)); }
3.2.3 限流
使用限流可以防止惡意攻擊。
可以使用 Redis 的計數(shù)器和時間窗口算法來將高并發(fā)請求控制在一個較低的速率內。
Java 實現(xiàn)簡單限流的代碼示例:
// 獲取當前時間戳。 long now = Instant.now().getEpochSecond(); // 在 Redis 中記錄這 1 秒鐘內的請求次數(shù)。 long current = redisTemplate.opsForValue().increment(key, 1); // 設置有效期為 1 秒鐘。 redisTemplate.expire(key, 1, TimeUnit.SECONDS); if(current > maxRequests) { // 請求次數(shù)超限,返回失敗。 return new Response(false, "too many requests"); } else { // 請求次數(shù)未超限。 // 如果是第一個請求,設置過期時間為 1 秒鐘。 redisTemplate.opsForValue().setIfAbsent(key, "", Duration.ofSeconds(1)); return new Response(true, ""); }
四、應用實踐
4.1 在 Spring Boot 中使用 Redis 緩存預熱和緩存穿透解決方案
在 Spring Boot 中,我們可以使用注解來實現(xiàn)緩存預熱和緩存穿透解決方案。
首先,我們需要添加 Spring Cache 和 Redis 相關的依賴,并配置 RedisTemplate 和緩存管理器。然后,我們可以在 Service 層的方法上使用 @Cacheable
注解來開啟緩存,例如:
@Service public class UserService { @Autowired private UserDao userDao; @Autowired private RedisTemplate<String, User> redisTemplate; @Cacheable(value = "user", key = "#id") public User get(int id) { // 直接從數(shù)據(jù)庫中獲取用戶。 return userDao.get(id); } }
4.2 在分布式系統(tǒng)中使用 Redis 緩存預熱和緩存穿透解決方案
在分布式系統(tǒng)中,我們可以使用 Redisson 或者其他類似的分布式鎖來避免重復預熱和處理緩存穿透。
例如,我們可以在所有服務器都停止服務前,將緩存數(shù)據(jù)寫入 Redis 中,并加上分布式鎖來保證只有一個服務能夠進行預熱。另外,我們也可以使用分布式鎖來避免緩存穿透導致的數(shù)據(jù)庫崩潰等問題。
到此這篇關于Redis中緩存預熱與緩存穿透解決方案的文章就介紹到這了,更多相關Redis 緩存預熱與緩存穿透內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Redis Desktop Manager(Redis可視化工具)安裝及使用圖文教程
這篇文章主要介紹了Redis Desktop Manager(Redis可視化工具)安裝及使用圖文教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04Jedis操作Redis實現(xiàn)模擬驗證碼發(fā)送功能
Redis是一個著名的key-value存儲系統(tǒng),也是nosql中的最常見的一種,這篇文章主要給大家介紹Jedis操作Redis實現(xiàn)模擬驗證碼發(fā)送功能,感興趣的朋友一起看看吧2021-09-09