【并發程式設計】java 如何解決redis緩存穿透、緩存雪崩(高性能示例代碼)
釋出時間:2018-11-22 16:48,
浏覽次數:872
, 标簽:
java
redis
<>緩存穿透
* 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; public
class ProductInfoCache { // Jedis 緩存對象 private JedisClient jedisClient; //
商品資訊XML映射類 private ProductInfoMapper productInfoMapper; // 緩存業務KEY字首 private
static final String PRODUCT_KEY = "項目名.子產品名.業務名."; // 鎖-執行個體 private Lock lock =
new ReentrantLock(); public synchronized String
getProductImgUrlById(String id){ // 擷取緩存 String product = jedisClient.get(
PRODUCT_KEY+ id); if (null == product) { // 如果沒有擷取鎖等待3秒,SECONDS代表:秒 try { if (
lock.tryLock(3, TimeUnit.SECONDS)) { try { // 擷取鎖後再查一次,查到了直接傳回結果 product =
jedisClient.get(PRODUCT_KEY + id); if (null == product) { // 查詢資料庫 product =
productInfoMapper.getProductInfoById(id); if (null == product) { //
假設有10000人的并發量,第一次查也沒有資料, // 那麼設定為"null",加入有效期6秒 jedisClient.setex((PRODUCT_KEY+
id), "null", 6); return product; } jedisClient.set((PRODUCT_KEY + id), product);
return product; } return product; } catch (Exception e) { product = jedisClient.
get(PRODUCT_KEY + id); } finally { // 釋放鎖(成功、失敗都必須釋放,如果是lock.tryLock()方法會一直阻塞在這)
lock.unlock(); } } else { product = jedisClient.get(PRODUCT_KEY + id); } }
catch (InterruptedException e) { product = jedisClient.get(PRODUCT_KEY + id); }
} 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
你的提問是小編創作靈感的來源!