http://blog.720ui.com/2016/redis_action_01_use_core/
如何使用緩存,怎么才能更加合理?今天的話題,結(jié)合我之前的項(xiàng)目場景,討論下使用緩存合理性問題。
熱點(diǎn)數(shù)據(jù),緩存才有價值
對于冷數(shù)據(jù)而言,大部分?jǐn)?shù)據(jù)可能還沒有再次訪問到就已經(jīng)被擠出內(nèi)存,不僅占用內(nèi)存,而且價值不大。
對于熱點(diǎn)數(shù)據(jù),比如我們的某IM產(chǎn)品,生日祝福模塊,當(dāng)天的壽星列表,緩存以后可能讀取數(shù)十萬次。再舉個例子,某導(dǎo)航產(chǎn)品,我們將導(dǎo)航信息,緩存以后可能讀取數(shù)百萬次。
頻繁修改的數(shù)據(jù),看情況考慮使用緩存
數(shù)據(jù)更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。
對于上面兩個例子,壽星列表、導(dǎo)航信息都存在一個特點(diǎn),就是信息修改頻率不高,讀取通常非常高的場景。
那存不存在,修改頻率很高,但是又不得不考慮緩存的場景呢?有!比如,這個讀取接口對數(shù)據(jù)庫的壓力很大,但是又是熱點(diǎn)數(shù)據(jù),這個時候就需要考慮通過緩存手段,減少數(shù)據(jù)庫的壓力,比如我們的某助手產(chǎn)品的,點(diǎn)贊數(shù),收藏?cái)?shù),分享數(shù)等是非常典型的熱點(diǎn)數(shù)據(jù),但是又不斷變化,此時就需要將數(shù)據(jù)同步保存到Redis緩存,減少數(shù)據(jù)庫壓力。
數(shù)據(jù)不一致性
一般會對緩存設(shè)置失效時間,一旦超過失效時間,就要從數(shù)據(jù)庫重新加載,因此應(yīng)用要容忍一定時間的數(shù)據(jù)不一致。還有一種是在數(shù)據(jù)更新時立即更新緩存,不過這也會更多系統(tǒng)開銷和事務(wù)一致性問題。
緩存更新機(jī)制
使用緩存過程中,我們經(jīng)常會遇到緩存數(shù)據(jù)的不一致性和與臟讀現(xiàn)象,我們有什么解決策略呢?
一般情況下,我們采取緩存雙淘汰機(jī)制,在更新數(shù)據(jù)庫的時候淘汰緩存。此外,設(shè)定超時時間,例如30分鐘。極限場景下,即使有臟數(shù)據(jù)入cache,這個臟數(shù)據(jù)也最多存在三十分鐘。
緩存可用性
緩存是提高數(shù)據(jù)讀取性能的,緩存數(shù)據(jù)丟失和緩存不可用不會影響應(yīng)用程序的處理。因此,一般的操作手段是,如果Redis出現(xiàn)異常,我們手動捕獲這個異常,記錄日志,并且去數(shù)據(jù)庫查詢數(shù)據(jù)返回給用戶。
緩存服務(wù)降級
服務(wù)降級的目的,是為了防止Redis服務(wù)故障,導(dǎo)致數(shù)據(jù)庫跟著一起發(fā)生雪崩問題。因此,對于不重要的緩存數(shù)據(jù),可以采取服務(wù)降級策略,例如一個比較常見的做法就是,Redis出現(xiàn)問題,不去數(shù)據(jù)庫查詢,而是直接返回默認(rèn)值給用戶。
緩存預(yù)熱
在新啟動的緩存系統(tǒng)中,如果沒有任何數(shù)據(jù),在重建緩存數(shù)據(jù)過程中,系統(tǒng)的性能和數(shù)據(jù)庫復(fù)制都不太好,那么最好的緩存系統(tǒng)啟動時就把熱點(diǎn)數(shù)據(jù)加載好,例如對于緩存信息,在啟動緩存加載數(shù)據(jù)庫中全部數(shù)據(jù)進(jìn)行預(yù)熱。一般情況下,我們會開通一個同步數(shù)據(jù)的接口,進(jìn)行緩存預(yù)熱。
緩存穿透
如果因?yàn)椴磺‘?dāng)?shù)臉I(yè)務(wù),或者惡意攻擊持續(xù)地發(fā)請求某些不存在的數(shù)據(jù),由于緩存沒有保存該數(shù)據(jù),所有的請求都會落到數(shù)據(jù)庫上,會對數(shù)據(jù)庫造成很大壓力,甚至奔潰。一個簡單的對策是將不存在的數(shù)據(jù)也緩存起來。