Java生鮮電商平臺-Redis緩存如何應對億級流量峯值(小程序/APP)

Java生鮮電商平臺-Redis緩存如何應對億級流量峯值(小程序/APP)

說明:Java生鮮電商平臺-緩存如何應對億級流量峯值許多大型互聯網系統,如:電商、社交、新聞等App  或網站,動輒日活千萬甚至上億,每分鐘的峯值流量也在數十萬以上,架構上

如何應對如此高的流量峯值?

     本節給大家介紹,通過使用“緩存”技術來給系統減壓。流量峯值對系統帶來的主要危害   在於,它會瞬間造成大量對磁盤數據的讀取和搜索,通常的數據源是數據庫或文件系統,

當數   據訪問量次數增大的時候,過多的磁盤讀取可能會最終成爲整個系統的性能瓶頸,甚至是壓垮   整個數據庫,導致系統卡死、服務不可用等嚴重後果。

 

 

          常規的應用系統中,我們通常會在需要的時候對數據庫進行查找,因此係統的大致結構如  下所示:

 

 

 圖 1.0 常規應用系統

                當數據量較高的時候,需要減少對於數據庫裏面的磁盤讀寫操作,因此通常都會選擇在業  務系統和數據庫之間加入一層緩存從而減少對數據庫方面的訪問壓力,如圖下圖所示。

              

 

圖1.1 增加了緩存層的應用系統

 

當數據量較高的時候,需要減少對於數據庫裏面的磁盤讀寫操作,因此通常都會選擇在業  務系統和MySQL 數據庫之間加入一個緩存層,從而減少對數據庫方面的訪問壓力。

緩存在實際場景的應用當中並非這麼簡單,下邊我們來通過幾個比較經典的緩存應用場景  來列舉一些問題:

 

1)緩存和數據庫之間數據一致性問題常用於緩存處理的機制有以下幾種:

Cache Aside 模式。這種模式處理緩存通常都是先從數據庫緩存查詢,如果緩存沒有命中則從數據庫中進行查找。

這裏面會發生的三種情況如下:

緩存命中:當查詢的時候發現緩存存在,那麼直接從緩存中提取。

緩存失效:當緩存沒有數據的時候,則從 database 裏面讀取源數據,再同步到 cache 裏面去。

緩存更新:當有新的寫操作去修改database 裏面的數據時,需要在寫操作完成之後,讓

cache 裏面對應的數據失效,作緩存同步。

這種Cache aside 模式,通常是我們在實際應用開發中最爲常用到的模式。但是並非說這種模式的緩存處理就一定能做到完美。

這種模式下依然會存在缺陷。比如,一個是讀操作,但是沒有命中緩存,然後就到數據庫   中取數據,此時來了一個寫操作,寫完數據庫後,讓緩存失效,然後之前的那個讀操作再把老   的數據放進去,所以會造成髒數據。

分佈式環境中要想完全的保證數據一致性,是一件極爲困難的事情,我們只能夠儘可能的  降低這種數據不一致性問題產生的情況。

 

Read Through 模式。是指應用程序始終從緩存中請求數據。如果緩存沒有數據,則它負責使用底層提供程序插件從數據庫中檢索數據。檢索數據後,緩存會自行更新並將數據返回給調   用應用程序。

使用Read Through 有一個好處,我們總是使用key 從緩存中檢索數據, 調用的應用程序不知道數據庫,由存儲方來負責自己的緩存處理,這使代碼更具可讀性,代碼更清晰。

但是這也有相應的缺陷,開發人員需要編寫相關的程序插件,增加了開發的難度性。

 

Write Through 模式。和Read Through 模式類似,當數據發生更新的時候,先去Cache 裏面進行更新,如果命中了,則先更新緩存再由Cache 方來更新database。如果沒有命中的話, 就直接更新Cache 裏面的數據。

 

Write Behind Caching 模式。這種模式通常是先將數據寫入到緩存裏面,然後再異步的寫入到database 中進行數據同步。

這樣的設計既可以直接的減少我們對於數據的database 裏面的直接訪問,降低壓力,同時對於database 的多次修改可以進行合併操作,極大的提升了系統的承載能力。

 

但是這種模式處理緩存數據具有一定的風險性,例如說當cache 機器出現宕機的時候,數據會有丟失的可能。

 

緩存的高併發場景中存在哪些問題?

緩存過期後將嘗試從後端數據庫獲取數據,這是一個看似合理的流程。

但是,在高併發場景下,有可能多個請求併發的去從數據庫獲取數據,對後端數據庫造成  極大的衝擊,甚至導致“雪崩”現象。

此外,當某個緩存key 在被更新時,同時也可能被大量請求在獲取,這也會導致一致性的問題。那如何避免類似問題呢?我們會想到類似“鎖”的機制,在緩存更新或者過期的情況下,   先嚐試獲取到鎖,當更新或者從數據庫獲取完成後再釋放鎖,其他的請求只需要犧牲一定的等待時間,即可直接從緩存中繼續獲取數據。

緩存穿透問題。緩存穿透也稱爲“擊穿”。很多朋友對緩存穿透的理解是:由於緩存故障或  者緩存過期導致大量請求穿透到後端數據庫服務器,從而對數據庫造成巨大沖擊。

這其實是一種誤解。真正的緩存穿透應該是這樣的:

在高併發場景下,如果某一個key 被高併發訪問,沒有被命中,出於對容錯性考慮,會嘗試去從後端數據庫中獲取,從而導致了大量請求達到數據庫,而當該key 對應的數據本身就是空的情況下,這就導致數據庫中併發的去執行了很多不必要的查詢操作,從而導致巨大沖擊和   壓力。

可以通過下面的幾種常用方式來避免緩存穿透問題:

1) 緩存空對象

對查詢結果爲空的對象也進行緩存,如果是集合,可以緩存一個空的集合(非null),如果是緩存單個對象,可以通過字段標識來區分。這樣避免請求穿透到後端數據庫。同時,也需   要保證緩存數據的時效性。

這種方式實現起來成本較低,比較適合命中不高,但可能被頻繁更新的數據。

2) 單獨過濾處理

對所有可能對應數據爲空的key  進行統一的存放,並在請求前做攔截,這樣避免請求穿透到後端數據庫。

這種方式實現起來相對複雜,比較適合命中不高,但是更新不頻繁的數據。

緩存顛簸問題。也被成爲“緩存抖動”,可以看做是一種比“雪崩”更輕微的故障,但是也會在一段時間內對系統造成衝擊和性能影響。一般是由於緩存節點故障導致。業內推薦的做法  

是通過一致性Hash 算法來解決。

 

緩存的雪崩。是指由於緩存的原因,導致大量請求到達後端數據庫,從而導致數據庫崩潰, 整個系統崩潰,發生災難。導致這種現象的原因有很多種,上面提到的“緩存併發”,“緩存

穿透”,“緩存顛簸”等問題,其實都可能會導致緩存雪崩現象發生。

這些問題也可能會被惡意攻擊者所利用。還有一種情況,例如某個時間點內,系統預加載   的緩存週期性集中失效了,也可能會導致雪崩。爲了避免這種週期性失效,可以通過設置不

同   的過期時間,來錯開緩存過期,從而避免緩存集中失效。

從應用架構角度,我們可以通過限流、降級、熔斷等手段來降低影響,也可以通過多級緩  存來避免這種災難。

此外,從整個研發體系流程的角度,應該加強壓力測試,儘量模擬真實場景,儘早的暴露  問題從而防範。

緩存技術,是大型互聯網系統架構中常用的一種技術,在設計緩存架構的過程中,要根據   業務場景進行鍼對性的設計,同步避免緩存延遲、髒數據、緩存雪崩等問題,提升系統的高可   用性,健壯性。

 

結語

覆盤與總結.

  總結:

          做Java生鮮電商平臺的互聯網應用,無論是生鮮小程序還是APP,Redis緩存設計是非常重要的,本文只是起一個拋磚引玉的作用,

          希望用生鮮小程序的搭建Java電商Redis緩存設計實戰經驗告訴大家一些實際的項目經驗,希望對大家有用.

 QQ:137071249

共同學習QQ羣:793305035

 

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