短影片全套原始碼,解決快取擊穿的常用方案
一、設定合理的過期時間
固定過期時間:為短影片全套原始碼中的熱點資料設定一個合理的固定過期時間,可以有效地減少資料庫的訪問頻率,但不能完全避免快取擊穿問題。
隨機過期時間:透過為短影片全套原始碼中的快取設定不同的隨機過期時間,可以使快取失效的時間點分散,減少同時大量請求資料庫的機率。
@Autowired private StringRedisTemplate redisTemplate; public String getDataWithRandomExpiration(String key) { String value = redisTemplate.opsForValue().get(key); if (value == null) { value = fetchDataFromDatabase(key); // 設定一個5到10分鐘的隨機過期時間 long timeout = 5L + new Random().nextInt(5); redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.MINUTES); } return value; } private String fetchDataFromDatabase(String key) { return "database-value"; }
二、使用互斥鎖
單體應用中的互斥鎖:在訪問資料庫前,使用 Java 的 synchronized 關鍵字或 ReentrantLock 類實現互斥鎖。
分散式環境的互斥鎖:使用 Redis 的 SETNX 命令實現分散式鎖,確保同一時間只有一個請求去短影片全套原始碼資料庫中查詢資料並更新快取。
@Autowired private StringRedisTemplate redisTemplate; public String getDataWithLock(String key) { String value = redisTemplate.opsForValue().get(key); if (value == null) { String lockKey = "lock:" + key; Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS); if (Boolean.TRUE.equals(acquired)) { try { value = redisTemplate.opsForValue().get(key); if (value == null) { value = fetchDataFromDatabase(key); redisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES); } } finally { redisTemplate.delete(lockKey); } } } return value; }
三、布隆過濾器
使用布隆過濾器預先判斷請求的資料是否可能存在於短影片全套原始碼的資料庫中,這樣可以避免對不存在的資料進行大量的資料庫查詢,減少資料庫的無效訪問。
@Autowired private StringRedisTemplate redisTemplate; @Autowired private BloomFilter<String> bloomFilter; public String getDataWithBloomFilter(String key) { if (!bloomFilter.mightContain(key)) { return null; // 假設資料不在資料庫中 } String value = redisTemplate.opsForValue().get(key); if (value == null) { value = fetchDataFromDatabase(key); redisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES); } return value; }
四、永不過期策略
對於短影片全套原始碼中某些極為重要的熱點資料,可以考慮將它們設定為永不過期,同時透過後臺執行緒定期更新這些資料。這種策略雖然保持資料的實時性不如上述方法,但可以最大限度防止資料庫的突發訪問壓力。
@Autowired private StringRedisTemplate redisTemplate; public String getAlwaysValidData(String key) { String value = redisTemplate.opsForValue().get(key); if (value == null) { value = fetchDataFromDatabase(key); redisTemplate.opsForValue().set(key, value); // 沒有設定過期時間 } return value; }
以上就是短影片全套原始碼,解決快取擊穿的常用方案, 更多內容歡迎關注之後的文章