缓存设计
1.前言&基本介紹
在原始的系統(tǒng)架構(gòu)中,我們都由程序直接連接DB,隨著業(yè)務(wù)的進(jìn)一步開展,DB的壓力越來越大,為了緩解DB的這一壓力,我們引入了緩存,在程序連接DB中加入緩存層,
從而減輕數(shù)據(jù)庫壓力,而且緩存一般存在于內(nèi)存中,相比于存在硬盤中的DB在讀取速度上絕對是比DB高幾個等級。下面我們來簡單聊聊關(guān)于緩存幾個東西
??
2.緩存的優(yōu)缺點
緩存的優(yōu)點就是“快”,一個快字基本能概括了。如上文說的加速讀寫,分流對數(shù)據(jù)庫的壓力,歸根結(jié)底就是對快字的應(yīng)用及其本身,缺點主要是如下三點:
1.數(shù)據(jù)不一致性:DB的數(shù)據(jù)與緩存中的數(shù)據(jù)不一致
2.開發(fā)成本:需要同時處理緩存層跟DB層的邏輯,增加了開發(fā)成本
3.維護(hù)成本:例如需要對緩存層進(jìn)行一個監(jiān)控,增加了運維的成本
?
3.緩存更新策略
? 在上面中我們說到數(shù)據(jù)不一致性,一般來說緩存也是需要有生命周期的,需要被更新或者刪除,這樣才能保持緩存的可控性,在緩存更新中有如下三點:
1.LR(F)U/FIFO算法刪除:簡單來說就是按照隊列的形式對不常用的緩存進(jìn)行刪除,鏈表的形式來實現(xiàn),具體可點這里http://blog.csdn.net/maddemon/article/details/6650703 2.超時刪除:在設(shè)置緩存的時候可以設(shè)置過期時間,在時間到期之后自動刪除。在使用這個的時候,最好還是確保緩存數(shù)據(jù)跟數(shù)據(jù)庫數(shù)據(jù)不一致的時候業(yè)務(wù)能容忍,還是存在一致性的問題 3.主動更新:應(yīng)用于對數(shù)據(jù)一致性要求高的,但最好還是需要保證更新的準(zhǔn)確性。假如對實時性要求不高的,還是根據(jù)超時刪除吧4.緩存粒度
假設(shè)一張用戶表有20個字段,那是否需要將全部字段都放到緩存中?這就涉及到一個粒度的問題!數(shù)據(jù)字段放少了,就會出現(xiàn)了不通用的問題;數(shù)據(jù)字段放多了,空間占用也多,序列化跟反序
列化消耗的性能更多了。在粒度這個問題上還是需要根據(jù)通用性,代碼維護(hù),性能跟空間占用這幾點上進(jìn)行考慮, 簡單來說就是靠經(jīng)驗了
?
5.緩存穿透
? 緩存穿透指的是查詢一個不存在的數(shù)據(jù),DB跟緩存都不會命中的數(shù)據(jù)。這樣的話每次查詢都會到DB層中查詢,DB層負(fù)載加大還有可能造成死機(jī),這樣緩存就失去了保護(hù)DB層的意義。出現(xiàn)這種情況有兩種:1.攻擊,爬蟲的大量請求;2.業(yè)務(wù)自身有問題。現(xiàn)在基本流行的解決方案有以下兩種:
? 5.1 緩存空對象,當(dāng)DB層也查不到數(shù)據(jù)的時候,緩存一個null值進(jìn)緩存,這樣下一次的話就直接從緩存中讀取,保護(hù)了后端。不過這種帶來的后果是緩存了更多的鍵,需要更多的空間,而且不可控性增加
5.2布隆過濾器攔截,它利用位數(shù)組很簡潔地表示一個集合,并能判斷一個元素是否屬于這個集合。這樣在查詢緩存之前先去過濾器中查詢緩存是否有存在該key。不過這個適合于數(shù)據(jù)量固定,實時性低的應(yīng)用中,因為要維護(hù)這一個過濾器。6.雪崩優(yōu)化
指的是原先的緩存層承載了大量的請求,有效的保護(hù)了DB層,但是假如緩存層炸了,那所有的請求都直接穿透到DB層,會容易造成DB層也炸了。就這個問題一直沒有一個很完美的解決方案,可以從下列兩個方面進(jìn)行思考:
6.1.保證緩存層的高可用(HA),例如redis的Sentinel跟Cluster都實現(xiàn)了高可用(在windows10下跑這個sentinel,偶爾會出現(xiàn)節(jié)點掛了但是sentinel沒反應(yīng)過來的情況,還是linux穩(wěn)定一點) 6.2.提前演練,這個類似與實驗設(shè)計,模擬某一層掛了的處理情況7.總結(jié)
最后用Xmind總結(jié)一下:
?
?
出處:http://www.cnblogs.com/powerdk/p/7116830.html
總結(jié)
- 上一篇: HBase - Filter - 过滤器
- 下一篇: 使用栈Stack实现队列Queue