精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Redis場景 | 緩存穿透、擊穿問題

數據庫 其他數據庫
由于緩存重建耗時較長,在這時間穿插線程2,3,4進入;那么這些線程都不能從緩存中查詢到數據,同一時間去訪問數據庫,同時的去執行數據庫操作代碼,對數據庫訪問壓力過大。

場景問題及原因

緩存穿透:

原因:客戶端請求的數據在緩存和數據庫中不存在,這樣緩存永遠不會生效,請求全部打入數據庫,造成數據庫連接異常。

解決思路:

  1. 緩存空對象
  2. 對于不存在的數據也在Redis建立緩存,值為空,并設置一個較短的TTL時間問題:實現簡單,維護方便,但短期的數據不一致問題

緩存雪崩:

原因:在同一時段大量的緩存key同時失效或者Redis服務宕機,導致大量請求到達數據庫,帶來巨大壓力。

解決思路:給不同的Key的TTL添加隨機值(簡單),給緩存業務添加降級限流策略(復雜),給業務添加多級緩存(復雜)

緩存擊穿(熱點Key):

前提條件:熱點Key&在某一時段被高并發訪問&緩存重建耗時較長

原因:熱點key突然過期,因為重建耗時長,在這段時間內大量請求落到數據庫,帶來巨大沖擊

解決思路:

  1. 互斥鎖
  2. 給緩存重建過程加鎖,確保重建過程只有一個線程執行,其它線程等待問題:線程阻塞,導致性能下降且有死鎖風險
  3. 邏輯過期
  4. 熱點key緩存永不過期,而是設置一個邏輯過期時間,查詢到數據時通過對邏輯過期時間判斷,來決定是否需要重建緩存;重建緩存也通過互斥鎖保證單線程執行,但是重建緩存利用獨立線程異步執行,其它線程無需等待,直接查詢到的舊數據即可問題:不保證一致性,有額外內存消耗且實現復雜

場景問題實踐解決

完整代碼地址:https://github.com/xbhog/hm-dianping

分支:20221221-xbhog-cacheBrenkdown

分支:20230110-xbhog-Cache_Penetration_Avalance

緩存穿透:

代碼實現:

12345678910111213141516171819202122public Shop queryWithPassThrough(Long id){
//從redis查詢商鋪信息
String shopInfo = stringRedisTemplate.opsForValue().get(SHOP_CACHE_KEY + id);
//命中緩存,返回店鋪信息
if(StrUtil.isNotBlank(shopInfo)){
return JSONUtil.toBean(shopInfo, Shop.class);
}
//redis既沒有key的緩存,但查出來信息不為null,則為空字符串
if(shopInfo != null){
return null;
}
//未命中緩存
Shop shop = getById(id);
if(Objects.isNull(shop)){
//將null添加至緩存,過期時間減少
stringRedisTemplate.opsForValue().set(SHOP_CACHE_KEY+id,"",5L, TimeUnit.MINUTES);
return null;
}
//對象轉字符串
stringRedisTemplate.opsForValue().set(SHOP_CACHE_KEY+id,JSONUtil.toJsonStr(shop),30L, TimeUnit.MINUTES);
return shop;
}

上述流程圖和代碼非常清晰,由于緩存雪崩簡單實現(復雜實踐不會)增加隨機TTL值,緩存穿透和緩存雪崩不過多解釋。

緩存擊穿:

緩存擊穿邏輯分析:

首先線程1在查詢緩存時未命中,然后進行查詢數據庫并重建緩存。注意上述緩存擊穿發生的條件,被高并發訪問&緩存重建耗時較長;

由于緩存重建耗時較長,在這時間穿插線程2,3,4進入;那么這些線程都不能從緩存中查詢到數據,同一時間去訪問數據庫,同時的去執行數據庫操作代碼,對數據庫訪問壓力過大。

互斥鎖:

解決方式:加鎖;****可以采用**tryLock方法 + double check**來解決這樣的問題

在線程2執行的時候,由于線程1加鎖在重建緩存,所以線程2被阻塞,休眠等待線程1執行完成后查詢緩存。由此造成在重建緩存的時候阻塞進程,效率下降且有死鎖的風險。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455private Shop queryWithMutex(Long id) {
//從redis查詢商鋪信息
String shopInfo = stringRedisTemplate.opsForValue().get(SHOP_CACHE_KEY + id);
//命中緩存,返回店鋪信息
if(StrUtil.isNotBlank(shopInfo)){
return JSONUtil.toBean(shopInfo, Shop.class);
}
//redis既沒有key的緩存,但查出來信息不為null,則為空字符串
if(shopInfo != null){
return null;
}
//實現緩存重建
String lockKey = "lock:shop:"+id;
Shop shop = null;
try {
Boolean aBoolean = tryLock(lockKey);
if(!aBoolean){
//加鎖失敗,休眠
Thread.sleep(50);
//遞歸等待
return queryWithMutex(id);
}
//獲取鎖成功應該再次檢測redis緩存是否還存在,做doubleCheck,如果存在則無需重建緩存。
synchronized (this){
//從redis查詢商鋪信息
String shopInfoTwo = stringRedisTemplate.opsForValue().get(SHOP_CACHE_KEY + id);
//命中緩存,返回店鋪信息
if(StrUtil.isNotBlank(shopInfoTwo)){
return JSONUtil.toBean(shopInfoTwo, Shop.class);
}
//redis既沒有key的緩存,但查出來信息不為null,則為“”
if(shopInfoTwo != null){
return null;
}
//未命中緩存
shop = getById(id);
// 5.不存在,返回錯誤
if(Objects.isNull(shop)){
//將null添加至緩存,過期時間減少
stringRedisTemplate.opsForValue().set(SHOP_CACHE_KEY+id,"",5L, TimeUnit.MINUTES);
return null;
}
//模擬重建的延時
Thread.sleep(200);
//對象轉字符串
stringRedisTemplate.opsForValue().set(SHOP_CACHE_KEY+id,JSONUtil.toJsonStr(shop),30L, TimeUnit.MINUTES);
}

} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
unLock(lockKey);
}
return shop;
}

在獲取鎖失敗時,證明已有線程在重建緩存,使當前線程休眠并重試(遞歸實現)。

代碼中需要注意的是synchronized關鍵字的使用,在獲取到鎖的時候,在判斷下緩存是否存在(失效)double-check,該關鍵字鎖的是當前對象。在其關鍵字{}中是同步處理。

推薦博客:https://blog.csdn.net/u013142781/article/details/51697672

然后進行測試代碼,進行壓力測試(jmeter),首先去除緩存中的值,模擬緩存失效。

設置1000個線程,多線程執行間隔5s。

所有的請求都是成功的,其qps大約在200,其吞吐量還是比較可觀的。然后看下緩存是否成功(只查詢一次數據庫);

邏輯過期:

思路分析:

當用戶開始查詢redis時,判斷是否命中,如果沒有命中則直接返回空數據,不查詢數據庫,而一旦命中后,將value取出,判斷value中的過期時間是否滿足,如果沒有過期,則直接返回redis中的數據,如果過期,則在開啟獨立線程后直接返回之前的數據,獨立線程去重構數據,重構完成后釋放互斥鎖。

封裝數據:這里我們采用新建實體類來實現

12345678910/**
* @author xbhog
* @describe:
* @date
@Data
public class RedisData {
private LocalDateTime expireTime;
private Object data;
}

使得過期時間和數據有關聯關系,這里的數據類型是Object,方便后續不同類型的封裝。

123456789101112131415161718192021222324252627282930313233343536373839public Shop queryWithLogicalExpire( Long id ) {
String key = CACHE_SHOP_KEY + id;
// 1.從redis查詢商鋪緩存
String json = stringRedisTemplate.opsForValue().get(key);
// 2.判斷是否存在
if (StrUtil.isBlank(json)) {
// 3.存在,直接返回
return null;
}
// 4.命中,需要先把json反序列化為對象
RedisData redisData = JSONUtil.toBean(json, RedisData.class);
Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);
LocalDateTime expireTime = redisData.getExpireTime();
// 5.判斷是否過期
if(expireTime.isAfter(LocalDateTime.now())) {
// 5.1.未過期,直接返回店鋪信息
return shop;
}
// 5.2.已過期,需要緩存重建
// 6.緩存重建
// 6.1.獲取互斥鎖
String lockKey = LOCK_SHOP_KEY + id;
boolean isLock = tryLock(lockKey);
// 6.2.判斷是否獲取鎖成功
if (isLock){
exectorPool().execute(() -> {
try {
//重建緩存
this.saveShop2Redis(id, 20L);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
unLock(lockKey);
}
});
}
// 6.4.返回過期的商鋪信息
return shop;
}

當前的執行流程跟互斥鎖基本相同,需要注意的是,在獲取鎖成功后,我們將緩存重建放到線程池中執行,來異步實現。

線程池代碼:

12345678910111213141516/**
* 線程池的創建
* @return
*/
private static ThreadPoolExecutor exectorPool(){
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5,
//根據自己的處理器數量+1
Runtime.getRuntime().availableProcessors()+1,
2L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
return executor;
}

緩存重建代碼:

1234567891011121314/**
* 重建緩存
* @param id 重建ID
* @param l 過期時間
*/
public void saveShop2Redis(Long id, long l){
//查詢店鋪信息
Shop shop = getById(id);
//封裝邏輯過期時間
RedisData redisData = new RedisData();
redisData.setData(shop);
redisData.setExpireTime(LocalDateTime.now().plusSeconds(l));
stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+id,JSONUtil.toJsonStr(redisData));
}

測試條件:100線程,1s線程間隔時間,緩存失效時間10s。

測試環境:緩存中存在對應的數據,并且在緩存快失效之前修改數據庫中的數據,造成緩存與數據庫不一致,通過執行壓測,來查看相關線程返回的數據情況。

從上述兩張圖中可以看到,在前幾個線程執行過程中店鋪name為102,當執行時間從19-20的時候店鋪name發生變化為105,滿足邏輯過期異步執行緩存重建的需求.?

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2020-03-16 14:57:24

Redis面試雪崩

2019-10-12 14:19:05

Redis數據庫緩存

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2022-03-08 00:07:51

緩存雪崩數據庫

2019-11-05 14:24:31

緩存雪崩框架

2024-04-07 00:00:02

Redis雪崩緩存

2023-04-14 07:34:19

2024-04-18 11:43:28

緩存數據庫Redis

2022-11-18 14:34:28

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2025-06-30 01:55:00

2023-11-10 14:58:03

2020-10-23 10:46:03

緩存雪崩擊穿

2024-03-12 10:44:42

2023-05-15 10:03:00

Redis緩存穿透

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2020-10-13 07:44:40

緩存雪崩 穿透

2025-10-20 07:49:26

穿透雪崩Redis
點贊
收藏

51CTO技術棧公眾號

国产精品嫩草69影院| 乱子伦一区二区| 无码视频在线观看| 国产精品99一区二区三| 日韩你懂的在线播放| 91视频 -- 69xx| 欧美一级二级三级区| 国产二区国产一区在线观看| 69影院欧美专区视频| 人妻少妇一区二区| 麻豆mv在线看| 国产精品天干天干在观线| 亚洲字幕一区二区| 黄色一级片免费在线观看| 日韩中字在线| 亚洲精美色品网站| www.精品在线| av白虎一区| 中文字幕在线观看不卡视频| 国产精品麻豆免费版| 中文字幕在线2018| 日韩视频一区| 欧美成人在线网站| 一级黄色片网址| 国产精品视频3p| 正在播放一区二区| 日韩av一二三四| 99爱在线视频| 亚洲免费色视频| 亚洲色图自拍| 黄色小视频在线观看| 成人一区二区在线观看| 成人日韩在线电影| 久久精品99北条麻妃| 亚洲美女网站| 欧美激情性做爰免费视频| 亚洲第一视频区| 亚洲欧洲av| 日韩av在线看| 毛茸茸free性熟hd| 日本一区二区三区视频在线看| 色系网站成人免费| 狠狠97人人婷婷五月| 欧美xxx黑人xxx水蜜桃| 亚洲人成影院在线观看| 中文精品一区二区三区 | 性欧美暴力猛交另类hd| 欧美成人精品一区| 久久久精品少妇| 久久中文视频| www.美女亚洲精品| 99自拍视频在线| 久久久久久久久国产一区| 在线成人中文字幕| 丁香激情五月少妇| 日本一区二区高清不卡| 国产亚洲一区二区精品| 色欲狠狠躁天天躁无码中文字幕 | 92国产精品观看| 国产精品视频福利| 丰满少妇被猛烈进入| 国产99久久久久久免费看农村| 91av一区二区三区| 亚洲h视频在线观看| 精品捆绑美女sm三区| 久久精品一区| 欧美激情欧美狂野欧美精品| 手机av在线看| 中文精品久久| 欧美富婆性猛交| 久久精品视频国产| 亚洲精品孕妇| 欧美专区在线观看| 探花国产精品一区二区| 美女在线观看视频一区二区| 国产日产欧美a一级在线| 88av在线视频| 国产精品88av| 久中文字幕一区| 搞黄视频在线观看| 亚洲视频一区二区在线观看| 神马午夜伦理影院| bl在线肉h视频大尺度| 欧美性少妇18aaaa视频| 奇米影视四色在线| 综合激情网...| 精品视频一区在线视频| 粉嫩精品久久99综合一区| 天天色综合色| 国内精品久久久久| 日韩欧美国产另类| 国产精品一二一区| 久久资源av| 成人影院在线观看| 狠狠躁天天躁日日躁欧美| 亚洲第一狼人区| 97久久综合区小说区图片区| 亚洲欧洲激情在线| 中文字幕另类日韩欧美亚洲嫩草| 日韩午夜在线电影| 国产专区欧美专区| 午夜精品久久久久久久91蜜桃| 97久久久精品综合88久久| 亚洲啪啪av| 91九色国产在线播放| 在线这里只有精品| 精品伦一区二区三区| 欧美色网址大全| 性色av一区二区三区| 136福利视频导航| 久久婷婷一区二区三区| 国产精品视频网站在线观看| 日韩天堂在线| 日韩av一区在线| 欧美精品乱码视频一二专区| 日本在线不卡一区| 九九九九九精品| 国产黄色小视频在线| 色伊人久久综合中文字幕| 精品人妻二区中文字幕| 欧美韩日高清| 国产成人+综合亚洲+天堂| 亚洲大尺度视频| 中文字幕在线不卡一区二区三区| 爱福利视频一区二区| 成人自拍在线| 欧美老肥婆性猛交视频| 在线观看中文字幕av| 久久久亚洲高清| 欧美国产日韩激情| 国产成人免费av一区二区午夜| 伊人久久精品视频| 国产精品777777| 99麻豆久久久国产精品免费| 国产情侣第一页| 国产精品麻豆| 超薄丝袜一区二区| 97国产精品久久久| 国产精品久久午夜| 蜜臀视频一区二区三区| 国产成人av| 日韩免费观看在线观看| 图片区 小说区 区 亚洲五月| 艳妇臀荡乳欲伦亚洲一区| 涩涩网站在线看| 国产精品久久久乱弄| 国产欧美日韩免费| 9i精品一二三区| 欧美日韩美少妇| 亚洲欧美精品久久| 国产真实乱偷精品视频免| 熟女视频一区二区三区| 色综合一区二区日本韩国亚洲| 社区色欧美激情 | 91免费视频播放| 亚洲欧美日韩在线播放| 国产又粗又猛大又黄又爽| 亚洲一本二本| 97se亚洲综合| heyzo中文字幕在线| 精品国产一区二区三区久久久蜜月| 午夜69成人做爰视频| 国产不卡视频在线观看| 蜜桃视频一区二区在线观看| 凹凸成人在线| 91大神福利视频在线| 九色在线视频| 欧美麻豆精品久久久久久| 手机看片久久| 欧美日韩亚洲视频| 北岛玲一区二区| 亚洲伊人观看| 欧美日韩在线精品| 日本国产欧美| 久久精品99久久久久久久久| 国产肥老妇视频| 午夜精品久久久久久久99水蜜桃| 国产精品三级在线观看无码| 日韩高清不卡在线| 欧美aaa在线观看| www.爱久久| 日韩美女av在线免费观看| 色多多视频在线观看| 欧美一级黄色大片| 久久国产黄色片| 国产精品成人网| 97精品人人妻人人| 日韩精品一二三区| 水蜜桃在线免费观看| 人人精品亚洲| 国产日本欧美在线观看| 精品丝袜在线| www.久久撸.com| 污视频软件在线观看| 欧美少妇性性性| 欧美人妻一区二区| 国产日韩精品视频一区| 亚洲欧美激情一区二区三区| 亚洲一区成人| 欧美在线观看黄| 成人免费在线播放| 国产三级精品在线不卡| 成人精品一区二区三区电影| 久久久久久久久电影| a√在线中文网新版址在线| 欧美成人性福生活免费看| 欧美日韩 一区二区三区| 一区二区三区国产精品| 天堂在线中文视频| 成人免费高清在线观看| 午夜免费看视频| 噜噜爱69成人精品| 免费在线看黄色片| 欧美成人精品一区二区三区在线看| 激情伦成人综合小说| 欧美黄色一级| 国产日韩欧美视频在线| 欧美男男tv网站在线播放| 久热精品视频在线| 国产精品麻豆一区二区三区| 亚洲精品美女在线| 亚洲国产精品久久人人爱潘金莲 | 日韩精品视频中文在线观看| 国产精品-色哟哟| 欧美性猛片xxxx免费看久爱| 国产69精品久久久久久久久久| 亚洲乱码日产精品bd| www.涩涩爱| 国产人成亚洲第一网站在线播放| 国产精品久久AV无码| 成人国产精品免费观看动漫| 黑人性生活视频| 激情文学综合插| 不用播放器的免费av| 免费久久99精品国产| 天天爽人人爽夜夜爽| 小嫩嫩精品导航| 国产一区二区在线视频播放| 一区视频在线看| 少妇久久久久久被弄到高潮| 欧美1区2区| 天天干天天色天天爽| 天天做天天爱天天综合网| 亚洲国产精品www| 日韩精品一区二区久久| 色综合久久88色综合天天提莫| 久久av免费看| 日本视频精品一区| 精品国产一级毛片| 日韩av电影免费播放| 菠萝蜜一区二区| 亚洲最新在线| 亚洲理论电影网| 日本三级中文字幕在线观看| 韩日在线一区| 国产白丝袜美女久久久久| 一本久道久久久| 92看片淫黄大片一级| 日韩黄色免费电影| 性猛交ⅹ×××乱大交| 九九在线精品视频| 亚洲AV无码久久精品国产一区| 国产成人综合视频| 国产一级免费片| 91丝袜呻吟高潮美腿白嫩在线观看| 免费成人深夜夜行p站| 国产亚洲女人久久久久毛片| 亚洲一二三精品| 综合久久国产九一剧情麻豆| 亚洲熟女www一区二区三区| 亚洲不卡在线观看| 亚洲不卡在线视频| 欧美日韩久久久久久| a视频免费在线观看| 亚洲国产成人久久综合| 精彩国产在线| 久久伊人91精品综合网站| 毛片在线导航| 国产成人极品视频| 粉嫩一区二区三区在线观看| 国产日韩欧美精品| 成人一区二区| av 日韩 人妻 黑人 综合 无码| 亚洲国产日韩在线| 中文字幕永久视频| 国产成人免费在线| 色无极影院亚洲| 中文字幕在线播放不卡一区| 粉嫩aⅴ一区二区三区| 欧美亚洲高清一区| 国精品人妻无码一区二区三区喝尿| 精品呦交小u女在线| 成人在线免费看黄| 国产999精品| 日韩精品亚洲专区在线观看| 久久综合福利| 欧美精品1区| 日韩中文字幕免费在线| 国产一区二区三区美女| 美女洗澡无遮挡| 一区二区三区欧美亚洲| 成年人晚上看的视频| 精品国内片67194| 日本中文字幕电影在线免费观看| 97av视频在线| 欧美2区3区4区| 亚洲激情一区二区| 国产欧美91| 男人操女人下面视频| 国产色91在线| 日韩欧美视频在线免费观看| 在线播放欧美女士性生活| 欧美69xxxxx| 欧美精品久久久久久久免费观看 | 欧美日韩视频在线观看一区二区三区 | 欧美性大战久久久久久久| 刘亦菲毛片一区二区三区| 色婷婷**av毛片一区| 国产欧美一区二区三区精品酒店| 99精品99久久久久久宅男| 成人在线免费观看网站| 女人扒开屁股爽桶30分钟| 波多野结衣亚洲一区| 欧美黄片一区二区三区| 51久久夜色精品国产麻豆| 成人免费高清在线播放| 欧美怡红院视频一区二区三区| 国产精品xxxav免费视频| 亚洲一区 在线播放| 极品少妇一区二区三区精品视频| 337人体粉嫩噜噜噜| 欧美午夜精品久久久久久浪潮 | 亚洲色图第一页| 日韩激情电影| 麻豆精品视频| 国产精品入口| aa片在线观看视频在线播放| 亚洲sss视频在线视频| 亚洲国产综合网| 欧美激情视频在线免费观看 欧美视频免费一| 久久夜夜久久| 一个色的综合| 久久精品国产99国产| 日韩av片在线免费观看| 欧美四级电影在线观看| av在线资源网| 国产日韩欧美在线视频观看| 91欧美在线| 亚洲综合在线一区二区| 亚洲免费视频中文字幕| 亚洲精品成人区在线观看| 久久久久久久久久久av| 久久精品66| 成年人观看网站| 国产亚洲成年网址在线观看| 一区二区三区麻豆| 日韩在线中文视频| 国产精久久久| 性一交一乱一伧国产女士spa| 成人污污视频在线观看| 日本中文字幕在线免费观看| 亚洲老头同性xxxxx| 国产一区一一区高清不卡| 亚洲啪啪av| 国产99一区视频免费| 国产污污视频在线观看| 国产午夜精品全部视频在线播放 | 一色桃子av在线| 国产精品免费看一区二区三区| 亚洲综合不卡| 特黄一区二区三区| 日韩精品在线看片z| 中国字幕a在线看韩国电影| 水蜜桃一区二区| 国产精品一区一区| 日本va欧美va国产激情| 国产一区二区三区四区福利| 999精品嫩草久久久久久99| 97在线国产视频| 国产人成亚洲第一网站在线播放| 国产日韩欧美一区二区东京热| 高清在线视频日韩欧美| 国产欧美一区| 国产又粗又猛大又黄又爽| 狠狠色噜噜狠狠狠狠97| 黄av在线播放| 欧洲高清一区二区| 国产精品66部| 精品成人无码久久久久久| 久久亚洲一区二区三区四区五区高| 欧美三级午夜理伦三级在线观看| 亚洲精品久久久久久宅男| 午夜精品久久久久久久久久久| www.亚洲免费| 久久99精品久久久久子伦| 极品销魂美女一区二区三区| 成人在线免费看视频| 色综合色综合久久综合频道88| 国产一区99| 大尺度做爰床戏呻吟舒畅|