緩存穿透
- 1、什麼是緩存穿透:
從字面上理解,緩存穿透就是運行程序擊穿了你的Redis緩存服務器,去訪問MySQL數據庫;
由於Redis存在一定的命中概率,進來的請求發現Redis中並沒有相關數據或者是沒有命中指定數據,會去數據庫查詢。- 2、緩存穿透有什麼危害:
如果大量請求進來,直接去訪問數據庫服務查詢,數據庫服務器CPU短時間內會超負載運行,致使數據庫服務宕機。
解決思路:
- 1、簡單:加synchronized關鍵字(同步鎖);
- 2、推薦:使用Lock對象的tryLock()方法(定時鎖);
package com.cn.seesun2012.cache;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.cn.seesun2012.mapper.ProductInfoMapper;
import com.cn.seesun2012.util.JedisClient;
/**
*
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████ ┃+
* ┃ ┃ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃
* ┃ ┃ + + + +
* ┃ ┃ God beast body, code no BUG
* ┃ ┃ + 神獸護體,代碼無BUG
* ┃ ┃
* ┃ ┃ +
* ┃ ┗━━━┓ + +
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*
* @title: 商品信息緩存-模塊
* @version v1.0.0
* @author csdn:seesun2012
* @date 2018年11月22日 下午17:21:33 週四
*
*/
public class ProductInfoCache {
// Jedis 緩存對象
private JedisClient jedisClient;
// 商品信息XML映射類
private ProductInfoMapper productInfoMapper;
// 緩存業務KEY前綴
private static final String PRODUCT_KEY = "項目名.模塊名.業務名.";
// 鎖-實例
private Lock lock = new ReentrantLock();
/**
* 獲取商品圖片路徑
* @param id
*/
public String getProductImgUrlById(String id){
// 獲取緩存
String product = jedisClient.get(PRODUCT_KEY + id);
if (null == product) {
try {
// 1秒內沒有獲取到鎖再走一遍,SECONDS代表秒
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try {
// 獲取鎖後再查一次,查到了直接返回結果
product = jedisClient.get(PRODUCT_KEY + id);
if (null == product) {
// 查詢數據庫
product = productInfoMapper.getProductInfoById(id);
if (null == product) {
// 假設有10000人的併發量,第一個人去查也沒有數據,
// 那麼設定爲"null",加入有效期6秒,防止DB崩潰
jedisClient.setex((PRODUCT_KEY+id), "null", 6);
return product;
}
jedisClient.set((PRODUCT_KEY + id), product);
return product;
}
return product;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 釋放鎖(成功、失敗都必須釋放,否則會一直阻塞在這)
lock.unlock();
}
} else {
getProductImgUrlById(id);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return product;
}
}
tryLock(long time, TimeUnit unit)方法和tryLock()方法是類似的,只不過區別在於這個方法在拿不到鎖時會等待一定的時間,在時間期限之內如果還拿不到鎖,就返回false;如果一開始拿到鎖或者在等待期間內拿到了鎖,則返回true。
Lock的使用法方法: https://blog.csdn.net/zengmingen/article/details/53259394?utm_source=blogxgwz7
緩存雪崩
- 1、什麼是緩存雪崩: 緩存在同一時間內大量鍵過期(失效),接着來的一大波請求瞬間都落在了數據庫中導致連接異常。
解決思路:
- 1、也是像解決緩存穿透一樣加鎖排隊,實現同上;
- 2、建立備份緩存,緩存A和緩存B,A設置超時時間,B不設值超時時間,先從A讀緩存,A沒有讀B,並且更新A緩存和B緩存;
布隆算法
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
持續更新中…
如有對思路不清晰或有更好的解決思路,歡迎與本人交流,QQ羣:273557553,個人微信:seesun2012
你的提問是小編創作靈感的來源!