緩存雪崩,緩存穿透解決方案

1. 緩存穿透:查詢一個必然不存在的數據。比如文章表,查詢一個不存在的id,每次都會訪問DB,如果有人惡意破壞,很可能直接對DB造成影響。

解決辦法:對所有可能查詢的參數以hash形式存儲,在控制層先進行校驗,不符合則丟棄。

2.緩存失效:如果緩存集中在一段時間內失效,DB的壓力凸顯。這個沒有完美解決辦法,但可以分析用戶行爲,儘量讓失效時間點均勻分佈。

 

 

緩存雪崩

緩存雪崩可能是因爲數據未加載到緩存中,或者緩存同一時間大面積的失效,從而導致所有請求都去查數據庫,導致數據庫CPU和內存負載過高,甚至宕機。

解決思路:

1,採用加鎖計數,或者使用合理的隊列數量來避免緩存失效時對數據庫造成太大的壓力。這種辦法雖然能緩解數據庫的壓力,但是同時又降低了系統的吞吐量。

2,分析用戶行爲,儘量讓失效時間點均勻分佈。避免緩存雪崩的出現。

3,如果是因爲某臺緩存服務器宕機,可以考慮做主備,比如:redis主備,但是雙緩存涉及到更新事務的問題,update可能讀到髒數據,需要好好解決。

 

緩存穿透

緩存穿透是指用戶查詢數據,在數據庫沒有,自然在緩存中也不會有。這樣就導致用戶查詢的時候,在緩存中找不到,每次都要去數據庫中查詢。

解決思路:

1,如果查詢也爲空,直接設置一個默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫,這種辦法最簡單粗暴。

2,根據緩存數據Key的規則。例如我們公司是做機頂盒的,緩存數據以Mac爲Key,Mac是有規則,如果不符合規則就過濾掉,這樣可以過濾一部分查詢。在做緩存規劃的時候,Key有一定規則的話,可以採取這種辦法。這種辦法只能緩解一部分的壓力,過濾和系統無關的查詢,但是無法根治。

3,採用布隆,將所有可能存在的數據哈希到一個足夠大的BitSet中,不存在的數據將會被攔截掉,從而避免了對存儲系統的查詢壓力。關於布隆,詳情查看:基於BitSet的布隆過濾器(Bloom Filter) 

大併發的緩存穿透會導致緩存雪崩。

 

緩存預熱

單機web系統情況下比較簡單。

解決思路:

1,直接寫個緩存刷新頁面,上線時手工操作下。

2,數據量不大,可以在WEB系統啓動的時候加載。

3,搞個定時刷新緩存,或者由用戶觸發都行。

緩存系統,如Memcached,Redis,比如緩存系統比較大,由十幾臺甚至幾十臺機器組成,這樣預熱會複雜一些。

解決思路:

1,寫個程序去跑。

2,單個緩存預熱。

緩存預熱的目標就是在系統上線前,將數據加載到緩存中。

 

緩存穿透

什麼是緩存穿透?

一般的緩存系統,都是按照key去緩存查詢,如果不存在對應的value,就應該去後端系統查找(比如DB)。如果key對應的value是一定不存在的,並且對該key併發請求量很大,就會對後端系統造成很大的壓力。這就叫做緩存穿透。  

如何避免?

1:對查詢結果爲空的情況也進行緩存,緩存時間設置短一點,或者該key對應的數據insert了之後清理緩存。 2:對一定不存在的key進行過濾。可以把所有的可能存在的key放到一個大的Bitmap中,查詢時通過該bitmap過濾。【感覺應該用的不多吧】

緩存雪崩

什麼是緩存雪崩?

當緩存服務器重啓或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給後端系統(比如DB)帶來很大壓力。

如何避免?

1:在緩存失效後,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。 2:不同的key,設置不同的過期時間,讓緩存失效的時間點儘量均勻。 3:做二級緩存,A1爲原始緩存,A2爲拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置爲短期,A2設置爲長期(此點爲補充)  

分佈式緩存系統

分佈式緩存系統面臨的問題

緩存一致性問題

1:緩存系統與底層數據的一致性。這點在底層系統是“可讀可寫”時,寫得尤爲重要 

2:有繼承關係的緩存之間的一致性。爲了儘量提高緩存命中率,緩存也是分層:全局緩存,二級緩存。他們是存在繼承關係的。全局緩存可以有二級緩存來組成。 

3:多個緩存副本之間的一致性。爲了保證系統的高可用性,緩存系統背後往往會接兩套存儲系統(如memcache,redis等)

緩存穿透和緩存雪崩

上面有講述。  

緩存數據的淘汰

緩存淘汰的策略有兩種: (1) 定時去清理過期的緩存。 (2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過期,過期的話就去底層系統得到新數據並更新緩存。  兩者各有優劣,第一種的缺點是維護大量緩存的key是比較麻煩的,第二種的缺點就是每次用戶請求過來都要判斷緩存失效,邏輯相對比較複雜,具體用哪種方案,大家可以根據自己的應用場景來權衡。   1. 預估失效時間 2. 版本號(必須單調遞增,時間戳是最好的選擇)3. 提供手動清理緩存的接口。

 

緩存算法

FIFO算法:First in First out,先進先出。原則:一個數據最先進入緩存中,則應該最早淘汰掉。也就是說,當緩存滿的時候,應當把最先進入緩存的數據給淘汰掉。
LFU算法:Least Frequently Used,最不經常使用算法。
LRU算法:Least Recently Used,近期最少使用算法。請查看:Memcached之你真正理解LRU嗎(4)

LRU和LFU的區別。LFU算法是根據在一段時間裏數據項被使用的次數選擇出最少使用的數據項,即根據使用次數的差異來決定。而LRU是根據使用時間的差異來決定的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章