国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

濱州網(wǎng)站建設(shè)phpi百度網(wǎng)盤(pán)帳號(hào)登錄入口

濱州網(wǎng)站建設(shè)phpi,百度網(wǎng)盤(pán)帳號(hào)登錄入口,怎樣知道網(wǎng)站有沒(méi)有做推廣,django做的網(wǎng)站舉例文章目錄一、緩存更新策略1、三種策略2、策略選擇3、主動(dòng)更新的方案二、緩存存在的問(wèn)題1、緩存穿透2、緩存雪崩3、緩存擊穿三、解決緩存問(wèn)題1、自定義分布式鎖2、解決緩存穿透問(wèn)題3、解決緩存擊穿問(wèn)題一、緩存更新策略 1、三種策略 內(nèi)存淘汰:redis自帶的內(nèi)存淘汰機(jī)…

文章目錄

    • 一、緩存更新策略
      • 1、三種策略
      • 2、策略選擇
      • 3、主動(dòng)更新的方案
    • 二、緩存存在的問(wèn)題
      • 1、緩存穿透
      • 2、緩存雪崩
      • 3、緩存擊穿
    • 三、解決緩存問(wèn)題
      • 1、自定義分布式鎖
      • 2、解決緩存穿透問(wèn)題
      • 3、解決緩存擊穿問(wèn)題

一、緩存更新策略

1、三種策略

  • 內(nèi)存淘汰:redis自帶的內(nèi)存淘汰機(jī)制
  • 過(guò)期淘汰:利用expire命令給數(shù)據(jù)設(shè)置過(guò)期時(shí)間
  • 主動(dòng)更新:主動(dòng)完成數(shù)據(jù)庫(kù)和緩存的同時(shí)更新

2、策略選擇

  • 低一致性需求:內(nèi)存淘汰或過(guò)期淘汰
  • 高一致性需求:主動(dòng)更新為主,過(guò)期淘汰兜底

3、主動(dòng)更新的方案

  • Cache Aside:緩存調(diào)用者在更新數(shù)據(jù)庫(kù)的同時(shí)完成對(duì)緩存的更新
    • 一致性良好
    • 實(shí)現(xiàn)難度一般
  • Read/Write Through:緩存與數(shù)據(jù)庫(kù)成為一個(gè)服務(wù),服務(wù)保證兩者的一致性,對(duì)外暴露的API接口。調(diào)用者調(diào)用API,無(wú)需知道自己操作的數(shù)據(jù)庫(kù)還是緩存,不關(guān)心一致性
    • 一致性?xún)?yōu)秀
    • 實(shí)現(xiàn)復(fù)雜
    • 性能一般
  • Write Back:緩存調(diào)用者的CRUD都針對(duì)緩存完成。由獨(dú)立線(xiàn)程異步的將緩存寫(xiě)到數(shù)據(jù)庫(kù),實(shí)現(xiàn)最終一致
    • 一致性差
    • 性能好
    • 實(shí)現(xiàn)復(fù)雜

二、緩存存在的問(wèn)題

1、緩存穿透

產(chǎn)生原因:客戶(hù)端請(qǐng)求的數(shù)據(jù)在緩存和數(shù)據(jù)庫(kù)中都不存在。當(dāng)這種情況大量出現(xiàn)或被惡意攻擊時(shí),接口的訪(fǎng)問(wèn)全部透過(guò)Redis訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),而數(shù)據(jù)庫(kù)中也沒(méi)有這些數(shù)據(jù),我們稱(chēng)這種現(xiàn)象為"緩存穿透"。

解決方案:

  1. 緩存空對(duì)象:對(duì)于不存在的數(shù)據(jù)也在Redis建立緩存,值為空,設(shè)置一個(gè)較短的TTL時(shí)間
    • 優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,維護(hù)方便
    • 缺點(diǎn):額外消耗內(nèi)存,短期的數(shù)據(jù)不一致
  2. 布隆過(guò)濾:利用布隆過(guò)濾算法,在請(qǐng)求Redis之前先判斷是否存在,如果不存在則直接拒絕訪(fǎng)問(wèn)
    • 優(yōu)點(diǎn):內(nèi)存占用少
    • 缺點(diǎn):實(shí)現(xiàn)復(fù)雜,存在誤判的可能性
  3. 其他方法:
    1. 做好數(shù)據(jù)的基礎(chǔ)格式校驗(yàn)
    2. 加強(qiáng)用戶(hù)權(quán)限校驗(yàn)
    3. 做好熱點(diǎn)數(shù)據(jù)的限流

布隆過(guò)濾器:

一種數(shù)據(jù)結(jié)構(gòu),由一串很長(zhǎng)的二進(jìn)制向量組成,可以將其看成一個(gè)二進(jìn)制數(shù)組。

當(dāng)要向布隆過(guò)濾器中添加一個(gè)元素key時(shí),我們通過(guò)多個(gè)hash函數(shù),算出一個(gè)值,然后將這個(gè)值所在的方格置為1。

因?yàn)槎鄠€(gè)不同的數(shù)據(jù)通過(guò)hash函數(shù)算出來(lái)的結(jié)果是會(huì)有重復(fù)的,所以布隆過(guò)濾器可以判斷某個(gè)數(shù)據(jù)一定不存在,但是無(wú)法判斷一定存在。

優(yōu)點(diǎn):優(yōu)點(diǎn)很明顯,二進(jìn)制組成的數(shù)組,占用內(nèi)存極少,并且插入和查詢(xún)速度都足夠快。

缺點(diǎn):隨著數(shù)據(jù)的增加,誤判率會(huì)增加;還有無(wú)法判斷數(shù)據(jù)一定存在;另外還有一個(gè)重要缺點(diǎn),無(wú)法刪除數(shù)據(jù)。

2、緩存雪崩

產(chǎn)生原因:在同一時(shí)間段大量的緩存key同時(shí)失效或者Redis服務(wù)宕機(jī),導(dǎo)致大量請(qǐng)求到達(dá)數(shù)據(jù)庫(kù),帶來(lái)巨大壓力

解決方案:

  1. 給不同的Key的TTL設(shè)置隨機(jī)值
  2. 利用Redis集群提高服務(wù)的可用性
  3. 誒緩存業(yè)務(wù)添加降級(jí)限流策略
  4. 給業(yè)務(wù)添加多級(jí)緩存

3、緩存擊穿

產(chǎn)生原因:熱點(diǎn)Key在某一個(gè)時(shí)間段被高并發(fā)訪(fǎng)問(wèn),而此時(shí)Key正好過(guò)期,如果重建緩存時(shí)間耗時(shí)長(zhǎng),在這段時(shí)間內(nèi)大量請(qǐng)求剾數(shù)據(jù)庫(kù),帶來(lái)巨大沖擊

解決方案:

  1. 設(shè)置value永不過(guò)期:通過(guò)定時(shí)任務(wù)進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)更新緩存,當(dāng)然前提時(shí)不會(huì)給數(shù)據(jù)庫(kù)造成壓力過(guò)大
    • 優(yōu)點(diǎn):最可靠,性能好
    • 缺點(diǎn):占空間,內(nèi)存消耗大,一致性差
  2. 互斥鎖:給緩存重建過(guò)程加鎖,確保重建過(guò)程只有一個(gè)線(xiàn)程執(zhí)行,其他線(xiàn)程等待
    • 優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,沒(méi)有額外內(nèi)存消耗,一致性好
    • 缺點(diǎn):等待導(dǎo)致性能下降,有死鎖風(fēng)險(xiǎn)
  3. 邏輯過(guò)期:熱點(diǎn)Key緩存永不過(guò)期,認(rèn)識(shí)設(shè)置一個(gè)邏輯過(guò)期時(shí)間,查詢(xún)到數(shù)據(jù)時(shí)通過(guò)對(duì)邏輯時(shí)間判斷,來(lái)決定是否需要進(jìn)行緩存重建。重建過(guò)程也通過(guò)互斥鎖來(lái)保證單線(xiàn)程執(zhí)行。利用獨(dú)立線(xiàn)程異步執(zhí)行,其他線(xiàn)程無(wú)需等待,直接查詢(xún)到舊的數(shù)據(jù)即可。
    • 優(yōu)點(diǎn):線(xiàn)程無(wú)需等待,性能較好
    • 缺點(diǎn):不保證一致性,有額外內(nèi)存消耗,實(shí)現(xiàn)復(fù)雜
private final RedisTemplate<String, String> redisTemplate;private static final ExecutorService CACHE_REBUILD_EXECUTOR = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(20), r -> new Thread(r, "cache_rebuild"));public CacheClient(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;
}public void setWithLogicalExpire(String key, Object value, Long expireTime, TimeUnit unit) {// 設(shè)置邏輯過(guò)期時(shí)間RedisData redisData = new RedisData();redisData.setValue(value);redisData.setExpireTime(LocalDateTime.now().plusNanos(unit.toNanos(expireTime)));redisTemplate.opsForValue().set(key, JSON.toJSONString(redisData));
}/*** 邏輯過(guò)期,互斥鎖獲取值,用于避免熱點(diǎn)數(shù)據(jù)出現(xiàn)緩存擊穿*/
public <R, V> R getMutex(String keyPrefix, V id, Class<R> clazz, Function<V, R> dbFallback, Long expireTime, TimeUnit unit) {String key = keyPrefix + id;String value = redisTemplate.opsForValue().get(key);if (StringUtils.isBlank(value)) {return null;}RedisData redisData = JSON.parseObject(value, RedisData.class);R result = JSONUtil.toBean((JSONObject) redisData.getValue(), clazz);if (redisData.getExpireTime().isAfter(LocalDateTime.now())) {return result;}// 如果緩存已過(guò)期,則嘗試更新String localKey = RedisConstant.LOCK + id;// 獲取鎖成功if (getLock(localKey)) {// 異步更新緩存CACHE_REBUILD_EXECUTOR.submit(() -> {try {R res = dbFallback.apply(id);this.setWithLogicalExpire(key, res, expireTime, unit);} catch (Exception e) {throw new RuntimeException(e);} finally {unLock(localKey);}});}return result;
}private boolean getLock(String key) {// 直接返回會(huì)進(jìn)行自動(dòng)拆箱,可能會(huì)出現(xiàn)空指針異常return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, "1"));
}private void unLock(String key) {redisTemplate.delete(key);
}

三、解決緩存問(wèn)題

1、自定義分布式鎖

/*** <pre>* 簡(jiǎn)易實(shí)現(xiàn)的Redis分布式鎖* </pre>** @author <a href="https://github.com/Ken-Chy129">Ken-Chy129</a>* @date 2023/2/26 21:18*/
public class SimpleRedisLock {private final RedisTemplate<String, String> redisTemplate;/**鎖的名字,根據(jù)業(yè)務(wù)設(shè)置*/private final String lockName;/*** key前綴*/private static final String KEY_PREFIX = "lock:";/*** value中線(xiàn)程標(biāo)識(shí)的前綴(為每個(gè)節(jié)點(diǎn)提供一個(gè)隨機(jī)的前綴,避免集群部署下線(xiàn)程id出現(xiàn)重復(fù)而導(dǎo)致value出現(xiàn)相同的情況)*/private static final String ID_PREFIX = UUID.fastUUID().toString(true);/*** 釋放鎖邏輯的lua腳本*/private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;static {UNLOCK_SCRIPT = new DefaultRedisScript<>();UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));UNLOCK_SCRIPT.setResultType(Long.class);}public SimpleRedisLock(String lockName, RedisTemplate<String, String> redisTemplate) {this.lockName = lockName;this.redisTemplate = redisTemplate;}public boolean tryLock(long timeoutSec) {long threadId = Thread.currentThread().getId();// 返回的是Boolean類(lèi)型,直接return會(huì)進(jìn)行自動(dòng)拆箱,可能會(huì)出現(xiàn)空指針異常// 需要為鎖設(shè)置過(guò)期時(shí)間,防止因服務(wù)宕機(jī)而導(dǎo)致鎖無(wú)法釋放return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + lockName, ID_PREFIX + threadId, timeoutSec, TimeUnit.SECONDS));}public void unlock() {redisTemplate.execute(UNLOCK_SCRIPT,Collections.singletonList(KEY_PREFIX + lockName),ID_PREFIX + Thread.currentThread().getId());}
}

Lua腳本——unlock.lua

--- 比較線(xiàn)程標(biāo)識(shí)與鎖中的標(biāo)識(shí)是否一致
if(redis.call('get', KEYS[1]) == ARGS[1]) then--- 釋放鎖return redis.call('del', KEYS[1])
end
return 0

使得釋放鎖的操作具有原子性

Redis是單線(xiàn)程處理,本身不會(huì)存在并發(fā)問(wèn)題,但是由于可能有多個(gè)客戶(hù)端訪(fǎng)問(wèn),每個(gè)客戶(hù)端會(huì)有一個(gè)線(xiàn)程,之間存在競(jìng)爭(zhēng),所以服務(wù)端收到的指令有可能出現(xiàn)多個(gè)客戶(hù)端的指令穿插,而lua腳本可以保證多條指令的原子性從而解決并發(fā)問(wèn)題

2、解決緩存穿透問(wèn)題

/*** 避免緩存穿透的獲取*/
public <R, V> R get(String keyPrefix, V id, Class<R> clazz, Function<V, R> dbFallback, Long expireTime, TimeUnit unit) {String key = keyPrefix + id;// 查詢(xún)緩存String value = redisTemplate.opsForValue().get(key);// 緩存存在則直接返回if (StringUtils.isNotBlank(value)) {return JSON.parseObject(value, clazz);}// 緩存不存在(到此處說(shuō)明value要么是空,要么是null)if (value != null) {// 不為null則說(shuō)明為“”,代表數(shù)據(jù)不存在,直接返回null,不用查詢(xún)數(shù)據(jù)庫(kù)(解決緩存穿透問(wèn)題)return null;}// value為null則查詢(xún)數(shù)據(jù)庫(kù)獲取數(shù)據(jù)進(jìn)行更新R result = dbFallback.apply(id);if (result == null) {// 數(shù)據(jù)庫(kù)查詢(xún)不到結(jié)果,則存入空串避免緩存穿透redisTemplate.opsForValue().set(key, "", RedisConstant.CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}// 查詢(xún)到結(jié)果,寫(xiě)回緩存this.set(key, result, expireTime, unit);return result;
}

3、解決緩存擊穿問(wèn)題

/*** 邏輯過(guò)期,互斥鎖獲取值,用于避免熱點(diǎn)數(shù)據(jù)出現(xiàn)緩存擊穿*/
public <R, V> R getMutex(String keyPrefix, V id, Class<R> clazz, Function<V, R> dbFallback, Long expireTime, TimeUnit unit) {String key = keyPrefix + id;String value = redisTemplate.opsForValue().get(key);if (StringUtils.isBlank(value)) {return null;}RedisData redisData = JSON.parseObject(value, RedisData.class);R result = JSONUtil.toBean((JSONObject) redisData.getValue(), clazz);if (redisData.getExpireTime().isAfter(LocalDateTime.now())) {return result;}// 如果緩存已過(guò)期,則獲取鎖嘗試更新SimpleRedisLock lock = new SimpleRedisLock(key, redisTemplate);// 獲取鎖成功if (lock.tryLock(5)) {// 異步更新緩存CACHE_REBUILD_EXECUTOR.submit(() -> {try {R res = dbFallback.apply(id);this.setWithLogicalExpire(key, res, expireTime, unit);} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}});}return result;
}
http://aloenet.com.cn/news/43075.html

相關(guān)文章:

  • 楊莊網(wǎng)站建設(shè)廣告推廣渠道有哪些
  • 龍崗企業(yè)網(wǎng)站制作公司資源
  • 微信公眾平臺(tái)官方網(wǎng)谷歌網(wǎng)站推廣優(yōu)化
  • 網(wǎng)站怎樣做自適應(yīng)分辨率大小公司網(wǎng)絡(luò)推廣該怎么做
  • laravel 做網(wǎng)站宣傳軟文
  • 微商水印相機(jī)做網(wǎng)站cps推廣平臺(tái)
  • 區(qū)塊鏈開(kāi)發(fā)技術(shù)的應(yīng)用做神馬seo快速排名軟件
  • 太原網(wǎng)站建設(shè)制作寧波seo優(yōu)化定制
  • 優(yōu)酷專(zhuān)門(mén)給馬天宇做的網(wǎng)站優(yōu)化大師下載安裝app
  • 東莞seo建站如何推廣長(zhǎng)沙服務(wù)好的網(wǎng)絡(luò)營(yíng)銷(xiāo)
  • 數(shù)商云價(jià)格江西seo推廣
  • virmach搭建wordpress蘇州seo網(wǎng)站推廣哪家好
  • 河北云建站鄭州seo優(yōu)化大師
  • 自己做盜版影視網(wǎng)站如何優(yōu)化培訓(xùn)體系
  • 微信漫畫(huà)網(wǎng)站模板百度外推代發(fā)排名
  • 開(kāi)平做網(wǎng)站百度官方版
  • 賣(mài)掉的網(wǎng)站了對(duì)方用來(lái)做違法短鏈接在線(xiàn)生成免費(fèi)
  • 各種網(wǎng)站解決方案免費(fèi)建站建站abc網(wǎng)站
  • go語(yǔ)言做的網(wǎng)站汕頭seo網(wǎng)站建設(shè)
  • 硬件開(kāi)發(fā)網(wǎng)站輿情分析系統(tǒng)
  • 做網(wǎng)站需要什么百度關(guān)鍵詞推廣價(jià)格
  • python網(wǎng)站開(kāi)發(fā)好嗎東莞seo外包
  • 域名解析網(wǎng)站鄭州網(wǎng)絡(luò)公司
  • 網(wǎng)站備案流程教程seo公司上海牛巨微
  • 網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)怎樣百度關(guān)鍵詞指數(shù)
  • 常州網(wǎng)站制作公司多嗎寶雞網(wǎng)站開(kāi)發(fā)公司
  • 蜜蜂vp加速器七天試用杭州優(yōu)化公司在線(xiàn)留言
  • 環(huán)保業(yè)網(wǎng)站建設(shè)的策劃軟文是指什么
  • 百度網(wǎng)站建設(shè)要多少錢(qián)春哥seo博客
  • 容桂銷(xiāo)售型網(wǎng)站建設(shè)知乎關(guān)鍵詞排名