摘要:關(guān)于緩存熱點(diǎn)重建原文說到在緩存失效的瞬間,有大量線程來重建緩存,造成后端負(fù)載加大,甚至可能會(huì)讓應(yīng)用崩潰,并給出互斥鎖和永遠(yuǎn)不過期兩種候選方案。即使繞過互斥鎖,也不會(huì)產(chǎn)生什么不好的后果,因?yàn)楦戮彺媸且粋€(gè)冪等操作。
向大家推薦這篇文章——Redis架構(gòu)之防雪崩設(shè)計(jì):網(wǎng)站不宕機(jī)背后的兵法
(另外推薦我去年的短文作為餐前點(diǎn)心——略談服務(wù)端緩存設(shè)計(jì))
《Redis架構(gòu)之防雪崩設(shè)計(jì)》這篇文章(下文稱之為“原文”)寫得非常好,全面概括了大規(guī)模系統(tǒng)可能面對(duì)的緩存穿透和緩存雪崩等問題,可以看出是一線實(shí)戰(zhàn)經(jīng)驗(yàn)的精華總結(jié),非常適合大家學(xué)習(xí)。
而我想再補(bǔ)充一些信息,使“原文”的版圖更加完整。
關(guān)于“緩存穿透”“原文”給出了空對(duì)象和布隆過濾器兩種解決方案。
空對(duì)象是首選方案,簡(jiǎn)單直接,碰到查詢結(jié)果為空的鍵,放一個(gè)空值在緩存中,下次再訪問就立刻知道這個(gè)鍵無效,不用發(fā)出SQL了。但“原文”也說了,存在如下問題:
第一,空值做了緩存,意味著緩存層中存了更多的鍵,需要更多的內(nèi)存空間 ( 如果是攻擊,問題更嚴(yán)重 ),比較有效的方法是針對(duì)這類數(shù)據(jù)設(shè)置一個(gè)較短的過期時(shí)間,讓其自動(dòng)剔除。第二,緩存層和存儲(chǔ)層的數(shù)據(jù)會(huì)有一段時(shí)間窗口的不一致,可能會(huì)對(duì)業(yè)務(wù)有一定影響。例如過期時(shí)間設(shè)置為 5 分鐘,如果此時(shí)存儲(chǔ)層添加了這個(gè)數(shù)據(jù),那此段時(shí)間就會(huì)出現(xiàn)緩存層和存儲(chǔ)層數(shù)據(jù)的不一致,此時(shí)可以利用消息系統(tǒng)或者其他方式清除掉緩存層中的空對(duì)象。
對(duì)于第一點(diǎn),我還建議空值放在另外的緩存空間中,不宜與正常值共用空間,否則當(dāng)空間不足時(shí),緩存系統(tǒng)的LRU算法可能會(huì)先剔除正常值,再剔除空值——這個(gè)漏洞可能會(huì)受到攻擊。
對(duì)于第二點(diǎn),如果是Redis緩存,更新數(shù)據(jù)后直接在Redis中清除即可;如果是本地緩存,就需要用消息來通知其他機(jī)器清除各自的本地緩存了。(業(yè)界終于接受了用消息來同步緩存的設(shè)計(jì)思想,cheers! )我有一個(gè)小項(xiàng)目joint-cache-redis來簡(jiǎn)單地演示“用消息來同步多個(gè)機(jī)器的緩存”,而且在實(shí)踐中發(fā)現(xiàn)Kafka可能比Redis MQ更適合于這個(gè)場(chǎng)景。
關(guān)于“緩存雪崩”這句概括很傳神!緩存層宕掉后,流量會(huì)像奔逃的野牛一樣,打向后端存儲(chǔ)
沒什么要補(bǔ)充的,就感謝一下Netflix開源的Hystrix吧!雖然只是一個(gè)庫,但是要實(shí)現(xiàn)可靠的限流算法還是頗有門道的。
關(guān)于“緩存熱點(diǎn) key 重建”“原文”說到在緩存失效的瞬間,有大量線程來重建緩存,造成后端負(fù)載加大,甚至可能會(huì)讓應(yīng)用崩潰,并給出“互斥鎖”和“永遠(yuǎn)不過期”兩種候選方案。
互斥鎖(Mutex):“分布式緩存加鎖”通常是一個(gè)反模式(見我去年的文章大型服務(wù)端開發(fā)的反模式第7條),如果持有鎖的實(shí)例不穩(wěn)定導(dǎo)致沒及時(shí)釋放,就會(huì)浪費(fèi)這個(gè)鎖,直到鎖過期?!霸摹钡淖髡哌€指出有死鎖的風(fēng)險(xiǎn)。
其實(shí)是可以優(yōu)化的:等待一兩次后,重試時(shí)可繞過互斥鎖。即使繞過互斥鎖,也不會(huì)產(chǎn)生什么不好的后果,因?yàn)楦戮彺媸且粋€(gè)冪等操作。
也可以把鎖的過期時(shí)間設(shè)得更短。
從這個(gè)例子我們能感覺到,冪等操作比非冪等操作更容易優(yōu)化。
永遠(yuǎn)不過期:"原文"很好地介紹了在Redis中的做法。對(duì)于Guava本地緩存就簡(jiǎn)單多了,使用refreshAfterWrite即可。
“原文”讀到最后,才知道這是《Redis開發(fā)與運(yùn)維》一書的節(jié)選,相信這本書會(huì)是國(guó)產(chǎn)技術(shù)書籍的精品!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/61856.html
摘要:在某些查詢中,可以將所有可能的查詢條件放入這個(gè)集合,在查詢之前使用這個(gè)集合對(duì)查詢條件進(jìn)行過濾,就可以避免緩存穿透的問題。解決方案二級(jí)緩存對(duì)于那些熱度高的數(shù)據(jù)設(shè)置二級(jí)緩存,并且錯(cuò)開和一級(jí)緩存的失效時(shí)間,使請(qǐng)求不會(huì)同時(shí)穿透兩層緩存去訪問數(shù)據(jù)庫 在我們的實(shí)際開發(fā)應(yīng)用中,緩存機(jī)制的廣泛存在,大大的提高了系統(tǒng)對(duì)數(shù)據(jù)庫的請(qǐng)求承受閾值,但是在一些特定的場(chǎng)景下,需要去了解它可能出現(xiàn)的問題和對(duì)應(yīng)的解決方...
摘要:緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù)。這就是緩存穿透請(qǐng)求的數(shù)據(jù)在緩存大量不命中,導(dǎo)致請(qǐng)求走數(shù)據(jù)庫。并發(fā)下解決數(shù)據(jù)庫與緩存不一致的思路將刪除緩存修改數(shù)據(jù)庫讀取緩存等的操作積壓到隊(duì)列里邊,實(shí)現(xiàn)串行化。 前言 只有光頭才能變強(qiáng)。 文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 回顧前面: 從零單排學(xué)Redis【青銅...
閱讀 3639·2021-09-22 15:02
閱讀 3993·2021-09-02 15:21
閱讀 2343·2019-08-30 15:55
閱讀 2933·2019-08-30 15:44
閱讀 923·2019-08-29 16:56
閱讀 2560·2019-08-23 18:22
閱讀 3480·2019-08-23 12:20
閱讀 3228·2019-08-23 11:28