8 回答

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊
補(bǔ)充:
緩存被“擊穿”問(wèn)題(以前看過(guò)一篇文章的做法,你可以借鑒一下):
業(yè)界比較常用的做法,是使用mutex。簡(jiǎn)單地來(lái)說(shuō),就是在緩存失效的時(shí)候(判斷拿出來(lái)的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者M(jìn)emcache的ADD)去set一個(gè)mutex key,當(dāng)操作返回成功時(shí),再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則,就重試整個(gè)get緩存的方法。類(lèi)似下面的代碼:
?public?String?get(key)?{ ??????String?value?=?redis.get(key); ??????if?(value?==?null)?{?//代表緩存值過(guò)期 ??????????//設(shè)置3min的超時(shí),防止del操作失敗的時(shí)候,下次緩存過(guò)期一直不能load?db ??????????if?(redis.setnx(key_mutex,?1,?3?*?60)?==?1)?{??//代表設(shè)置成功 ???????????????value?=?db.get(key); ??????????????????????redis.set(key,?value,?expire_secs); ??????????????????????redis.del(key_mutex); ??????????????}?else?{??//這個(gè)時(shí)候代表同時(shí)候的其他線程已經(jīng)load?db并回設(shè)到緩存了,這時(shí)候重試獲取緩存值即可 ??????????????????????sleep(50); ??????????????????????get(key);??//重試 ??????????????} ??????????}?else?{ ??????????????return?value;?????? ??????????} ??}

TA貢獻(xiàn)1936條經(jīng)驗(yàn) 獲得超7個(gè)贊
你這個(gè)問(wèn)題就是比較經(jīng)典的緩存穿透問(wèn)題了,可以考慮兩個(gè)方法
1.該key永不過(guò)期,寫(xiě)個(gè)定時(shí)腳本定期刷新結(jié)果,寫(xiě)入該key
2.或者加個(gè)訪問(wèn)鎖。緩存更新期間的時(shí)候,set(lock, 1),然后其他請(qǐng)求發(fā)現(xiàn)lock=1,給個(gè)友好提示什么的,更新成功后,lock置為0。大原則上,寧愿用戶(hù)體驗(yàn)差一些,也不能因?yàn)榫彺娲┩秆┍缹?dǎo)致宕機(jī)。

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個(gè)贊
3600秒自動(dòng)銷(xiāo)毀,你可以在3500秒的時(shí)候重新生成緩存,在緩存失效前刷新緩存。

TA貢獻(xiàn)1773條經(jīng)驗(yàn) 獲得超3個(gè)贊
并發(fā)導(dǎo)致的問(wèn)題,首先考慮鎖的機(jī)制來(lái)解決問(wèn)題,可以使用redis 的setnx實(shí)現(xiàn)鎖的,保證每次只有一個(gè)請(qǐng)求load數(shù)據(jù),數(shù)據(jù)更新完,進(jìn)行解鎖
- 8 回答
- 0 關(guān)注
- 1380 瀏覽
添加回答
舉報(bào)