PHP之快取雪崩,及解決方法

2021-09-09 01:33:14 字數 1713 閱讀 4122

一、什麼是快取雪崩

快取雪崩就是指快取由於某些原因(比如 宕機、cache服務掛了或者不響應)整體crash掉了,導致大量請求到達後端資料庫,從而導致資料庫崩潰,整個系統崩潰,發生災難。

下面的就是乙個雪崩的簡單過程:

1、redis集群徹底崩潰

2、快取服務大量對redis的請求hang住,占用資源

3、快取服務大量的請求打到源頭服務去查詢mysql,直接打死mysql

4、源頭服務因為mysql***也崩潰,對源服務的請求也hang住,占用資源

5、快取服務大量的資源全部耗費在訪問redis和源服務無果,最後自己被拖死,無法提供服務

6、nginx無法訪問快取服務,redis和源服務,只能基於本地快取提供服務,但是快取過期後,沒有資料提供

7、**崩潰

通俗來講:就像雪崩一樣 你乙個雪塊砸了下來 是不是剩下的都會持續下落 造成一種雪崩

導致這種現象可能的原因:

1、例如 「快取併發」,「快取穿透」,「快取顛簸」 等問題,這些問題也可能會被惡意攻擊者所利用。

2、例如 某個時間點內,系統預載入的快取週期性集中失效了。解決方法:可以通過設定不同的過期時間,來錯開快取過期,從而避免快取集中失效。

快取穿透

快取穿透,是指查詢乙個資料庫一定不存在的資料。正常的使用快取流程大致是,資料查詢先進行快取查詢,如果key不存在或者key已經過期,再對資料庫進行查詢,並把查詢到的物件,放進快取。如果資料庫查詢物件為空,則不放進快取

快取擊穿

快取擊穿,是指乙個key非常熱點,在不停的扛著大併發,大併發集中對這乙個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在乙個屏障上鑿開了乙個洞。

解決的方案

快取雪崩的解決方案

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,單個快取預熱框架。

快取預熱的目標就是在系統上線前,將資料載入到快取中。

memcache 快取雪崩現象及解決方法

1 什麼是memcache雪崩 快取雪崩一般是由某個快取節點失效,導致其他節點的快取命中率下降,快取中缺失的資料 memcache經典場景,當有乙個客戶端的服務請求過來的時候,首先去查 memcache,memcache裡面是否快取過了這個資料,如果沒有這個資料,我們就去資料庫查詢,如果有這個資料,...

快取失效 穿透 併發 雪崩問題及解決方法

1 快取失效 引起這個原因的主要因素是高併發下,一般設定乙個快取的過期時間時,併發很高時可能會出在某乙個時間同時生成很多的快取,並且過期時間在同一時刻,這個時候就可能引發 當過期時間到後,這些快取同時失效,請求全部 到db,db可能會壓力過重。處理方法 將快取失效時間分散開,不要所以快取時間長度都設...

快取失效 穿透 併發 雪崩問題及解決方法

1 快取失效 引起這個原因的主要因素是高併發下,一般設定乙個快取的過期時間時,併發很高時可能會出在某乙個時間同時生成很多的快取,並且過期時間在同一時刻,這個時候就可能引發 當過期時間到後,這些快取同時失效,請求全部 到db,db可能會壓力過重。處理方法 將快取失效時間分散開,不要所以快取時間長度都設...