做外匯網(wǎng)站短視頻seo詢盤獲客系統(tǒng)軟件
1、我看你做的項(xiàng)目中,都用到了redis,你在最近的項(xiàng)目中哪些場景使用了redis呢?
2、緩存穿透
布隆過濾器的誤判現(xiàn)象
Redisson和Guava都對布隆過濾器進(jìn)行了實(shí)現(xiàn)
3、緩存擊穿
?
互斥鎖,就是一個(gè)線程來修改,并占據(jù)了鎖,另外其他的線程想要訪問必須拿到鎖,否則就休眠重試,等到修改線程結(jié)束后把鎖釋放了,緩存中也就有新的數(shù)據(jù),這個(gè)時(shí)候其他線程也可以拿到數(shù)據(jù)了。
設(shè)置邏輯過期,沒有那么的強(qiáng)一致性,但是整體性能 很高,先讓線程去拿老的數(shù)據(jù),另外開一個(gè)線程去更新數(shù)據(jù),其他線程來了也會第一時(shí)間拿到老的數(shù)據(jù)
4、緩存雪崩
5、MySQL怎么跟Redis保持一致?
第一種方式:延時(shí)雙刪
先刪除緩存,還是先修改數(shù)據(jù)庫?都會有問題
先刪緩存在改數(shù)據(jù)庫的情況
正常情況:
異常情況:初始: 緩存是20,數(shù)據(jù)庫是10,線程1是修改操作,線程1先把20的緩存刪除掉了,線程2查詢不到緩存,接著查數(shù)據(jù)庫查到了10,把10寫入到了緩存中,然后線程2又把數(shù)據(jù)庫給更新為20,現(xiàn)在緩存是10,數(shù)據(jù)庫卻是20
先操作數(shù)據(jù)庫再刪緩存的情況
正常情況
異常情況:
延時(shí)的原因是因?yàn)閿?shù)據(jù)庫是主從的,延時(shí)一段時(shí)間保證從庫已經(jīng)完成了主庫發(fā)來的更改
第二種方案 可以使用共享鎖+排他鎖的方案來解決緩存一致性的問題
第三種方案 異步通知保證數(shù)據(jù)的最終一致性
?
6、Redis的持久化
7、Redis的過期策略
惰性刪除
定期刪除
8、Redis的數(shù)據(jù)淘汰策略
9、分布式鎖
分布式鎖的使用場景:集群情況下的定時(shí)任務(wù)、搶單、冪等性等場景
lock.tryLock(第一個(gè)參數(shù)表示等待鎖的最大嘗試時(shí)間,第二個(gè)參數(shù)表示鎖的自動釋放時(shí)間(此時(shí)看門狗就不會生效了,因?yàn)閞edisson認(rèn)為你自己有控制鎖時(shí)長的能力,第三個(gè)參數(shù)是時(shí)間單位)),加鎖、設(shè)置過期時(shí)間等操作都是基于LUA腳本完成的
9.1、Redisson是可重入鎖嗎?
10、Redis的集群方案
11、Redisson獲取鎖的源碼分析
11.1、redissonClient.getLock
getLock的過程就是對底層的數(shù)據(jù)做一些準(zhǔn)備工作,這個(gè)時(shí)候鎖還沒有放到redis中去
11.2、lock.lock()
執(zhí)行完lua腳本后,在redis里就有鎖了
11.3、鎖的續(xù)期
看門狗續(xù)期
每 過期時(shí)間/3 時(shí)間段過后,就會對鎖進(jìn)行一個(gè)續(xù)期
11.4、鎖的釋放
11.5、Redisson是可重入鎖嗎?
第一次上鎖redis中的狀態(tài):
第二次上鎖redis中的狀態(tài):
然后第一次釋放鎖:
然后第二次釋放鎖:
11.6、實(shí)現(xiàn)分布式鎖需要注意哪些問題?
11.6.1、不是原子操作
獲取鎖+設(shè)置過期時(shí)間寫成一行
11.6.2、沒有釋放鎖
設(shè)置過期時(shí)間 + 手動釋放來保證鎖一定會被釋放
11.6.3、釋放了鎖,但是業(yè)務(wù)還沒執(zhí)行完
鎖過期時(shí)間30s,但是業(yè)務(wù)執(zhí)行了35s,另外的線程就可以拿到鎖,可能造成數(shù)據(jù)的不一致
業(yè)務(wù)沒執(zhí)行完,就續(xù)期
11.6.4、釋放了別人的鎖
- 可以加鎖的時(shí)候給key加一個(gè)UUID
- 釋放鎖之前判斷是否還是當(dāng)前線程
-
if (lock.isHeldByCurrentThread()) {lock.unlock();}
11.6.5、大量請求競爭鎖失敗
- 重試
- 讓業(yè)務(wù)執(zhí)行時(shí)間盡可能短
- 限流