所謂多級快取,即在整個系統架構的不同系統層級進行資料快取,以提公升訪問效率,這也是應用最廣的方案之一。我們應用的整體架構如圖1所示:
億級請求下多級快取那些事,你全部吃下了嗎?
圖1 多級快取方案
文末有福利贈送,如果你感興趣的話可以去領取架構資料。
整體流程如上圖所示:
1)首先接入nginx將請求負載均衡到應用nginx,此處常用的負載均衡演算法是輪詢或者一致性雜湊,輪詢可以使伺服器的請求更加均衡,而一致性雜湊可以提公升應用nginx的快取命中率,相對於輪詢,一致性雜湊會存在單機熱點問題,一種解決辦法是熱點直接推送到接入層nginx,一種辦法是設定乙個閥值,當超過閥值,改為輪詢演算法。
2)接著應用nginx讀取本地快取(本地快取可以使用lua shared dict、nginx proxy cache(磁碟/記憶體)、local redis實現),如果本地快取命中則直接返回,使用應用nginx本地快取可以提公升整體的吞吐量,降低後端的壓力,尤其應對熱點問題非常有效。
3)如果nginx本地快取沒命中,則會讀取相應的分布式快取(如redis快取,另外可以考慮使用主從架構來提公升效能和吞吐量),如果分布式快取命中則直接返回相應資料(並回寫到nginx本地快取)。
4)如果分布式快取也沒有命中,則會回源到tomcat集群,在回源到tomcat集群時也可以使用輪詢和一致性雜湊作為負載均衡演算法。
5)在tomcat應用中,首先讀取本地堆快取,如果有則直接返回(並會寫到主redis集群),為什麼要加一層本地堆快取將在快取崩潰與快速修復部分細聊。
6)作為可選部分,如果步驟4沒有命中可以再嘗試一次讀主redis集群操作。目的是防止當從有問題時的流量衝擊。
7)如果所有快取都沒有命中只能查詢db或相關服務獲取相關資料並返回。
8)步驟7返回的資料非同步寫到主redis集群,此處可能多個tomcat例項同時寫主redis集群,可能造成資料錯亂,如何解決該問題將在更新快取與原子性部分細聊。
應用整體分了三部分快取:應用nginx本地快取、分布式快取、tomcat堆快取,每一層快取都用來解決相關的問題,如應用nginx本地快取用來解決熱點快取問題,分布式快取用來減少訪問回源率、tomcat堆快取用於防止相關快取失效/崩潰之後的衝擊。
雖然就是加快取,但是怎麼加,怎麼用細想下來還是有很多問題需要權衡和考量的,接下來部分我們就詳細來討論一些快取相關的問題。
接下來部將從快取過期、維度化快取、增量快取、大value快取、熱點快取幾個方面來詳細介紹如何快取資料。
對於快取的資料我們可以考慮不過期快取和帶過期時間快取,什麼場景應該選擇哪種模式需要根據業務和資料量等因素來決定。
不過期快取場景一般思路如圖2所示:
億級請求下多級快取那些事,你全部吃下了嗎?
圖2不過期快取方案
使用cache-aside模式,首先寫資料庫,如果成功,則寫快取。這種場景下存在事務成功、快取寫失敗但無法回滾事務的情況。另外,不要把寫快取放在事務中,尤其寫分布式快取,因為網路抖動可能導致寫快取響應時間很慢,引起資料庫事務阻塞。如果對快取資料一致性要求不是那麼高,資料量也不是很大,則可以考慮定期全量同步快取。
也有提到如下思路:先刪快取,然後執行資料庫事務;不過這種操作對於如商品這種查詢非常頻繁的業務不適用,因為在你刪快取的同時,已經有另乙個系統來讀快取了,此時事務還沒有提交。當然對於如使用者維度的業務是可以考慮的。
不過為了更好地解決以上多個事務的問題,可以考慮使用訂閱資料庫日誌的架構,如使用canal訂閱mysql的binlog實現快取同步。
對於長尾訪問的資料、大多數資料訪問頻率都很高的場景、快取空間足夠都可以考慮不過期快取,比如使用者、分類、商品、**、訂單等,當快取滿了可以考慮lru機制驅逐老的快取資料。
1. 過期快取機制
即採用懶載入,一般用於快取別的系統的資料(無法訂閱變更訊息、或者成本很高)、快取空間有限、低頻熱點快取等場景;常見步驟是:首先讀取快取如果不命中則查詢資料,然後非同步寫入快取並過期快取,設定過期時間,下次讀取將命中快取。熱點資料經常使用即在應用系統上快取比較短的時間。這種快取可能存在一段時間的資料不一致情況,需要根據場景來決定如何設定過期時間。如庫存資料可以在前端應用上快取幾秒鐘,短時間的不一致時可以忍受的。
2. 維度化快取與增量快取
對於電商系統,乙個商品可能拆成如基礎屬性、列表、上下架、規格引數、商品介紹等;如果商品變更了要把這些資料都更新一遍那麼整個更新成本很高:介面呼叫量和頻寬;因此最好將資料進行維度化並增量更新(只更新變的部分)。尤其如上下架這種只是乙個狀態變更,但是每天頻繁呼叫的,維度化後能減少服務很大的壓力。
億級請求下多級快取那些事,你全部吃下了嗎?
圖3 維度化快取方案
按照不同維度接收mq進行更新。
3. 大value 快取
要警惕快取中的大value,尤其是使用redis時。遇到這種情況時可以考慮使用多執行緒實現的快取,如memcached,來快取大value;或者對value進行壓縮;或者將value拆分為多個小value,客戶端再進行查詢、聚合。
4. 熱點快取
對於那些訪問非常頻繁的熱點快取,如果每次都去遠端快取系統中獲取,可能會因為訪問量太大導致遠端快取系統請求過多、負載過高或者頻寬過高等問題,最終可能導致快取響應慢,使客戶端請求超時。一種解決方案是通過掛更多的從快取,客戶端通過負載均衡機制讀取從快取系統資料。不過也可以在客戶端所在的應用/ **層本地儲存乙份,從而避免訪問遠端快取,即使像庫存這種資料,在有些應用系統中也可以進行幾秒鐘的本地快取,從而降低遠端系統的壓力。
億級請求下多級快取那些事,你全部吃下了嗎?
當然還有更多,這邊就不一一枚舉了,你如果覺得你能全部吃下,也不擋著你要到更多。
為什麼某些人會一直比你優秀,是因為他本身就很優秀還一直在持續努力變得更優秀。而你是不是還在滿足於現狀且內心在竊喜?「對於程式設計師來說,如果哪一天開始他停止了學習,那麼他的職業生涯便開始宣告消亡。」所以行動起來,學習起來!
億級請求下多級快取那些事
什麼是多級快取 所謂多級快取,即在整個系統架構的不同系統層級進行資料快取,以提公升訪問效率,這也是應用最廣的方案之一。我們應用的整體架構如圖1所示 圖1 多級快取方案 整體流程如上圖所示 1 首先接入nginx將請求負載均衡到應用nginx,此處常用的負載均衡演算法是輪詢或者一致性雜湊,輪詢可以使伺...
億級流量系統多級快取架構8 服務降級
在高併發場景下,當系統中的一些功能元件出現異常,無法繼續提供伺服器的時候,為了保證整體系統可用性,可以犧牲一部分功能依舊提供有損服務 服務等級定義 sla service level agreement 是判定壓測是否異常的重要依據。壓測過程中,通過監控核心服務狀態的 sla 指標資料,您可以更直觀...
億級流量系統多級快取架構9 分布式事務
mysql中,我們可以使用begin開始事務,rollback回滾事務,commit提交事務 redolog 記錄變更 undolog回滾 spring中,使用 transaction標記事務 原子性 atomic 要麼全部成功,要麼全部失敗,沒有中間狀態 一致性 consistency 指的是在執...