系統效能提升優先法寶|快取應用實踐

java填坑路發表於2018-12-10

快取是系統效能提升優先法寶,在網際網路應用系統中,屢試不爽。網上有很多資料介紹快取理論及使用策略,本文就不再涉及了,今天簡單將快取做個歸類,重點分享以前在實際業務中碰到場景以及如何使用。

接下來主要分兩部分介紹:快取分類與應用實踐案例。

快取分類

快取一般有以下幾類:客戶端、瀏覽器、CDN快取、NGINX快取、應用快取及統一快取(如redis)。

▲快取分類:使用者->資料層

客戶端快取:很少使用,一般都是傳統企業才會使用。把不變化或很長時間才變化的資料按一定格式儲存在客戶端的本地檔案中,使用時通過js讀取解析使用,延用了C/S結構的方式,適合資料量很大業務且技術有所不足的開發。

瀏覽器快取:這種形式使用很廣泛,極大地提升了使用者體驗,但有時會出現沒及時更新導致顯示“錯誤”的資訊。把已經請求過的Web資源(如html頁面,圖片,js,css等)拷貝一份副本儲存在瀏覽器中,快取會根據進來的請求儲存輸出內容的副本。這種快取帶來的好處有三點:減少網路頻寬消耗,降低伺服器壓力,減少網路延遲、加快頁面開啟速度,適合請求量大、靜態的資料請求。

CDN快取:在使用者和伺服器之間增加cache層,把資料存放到內容分發網路機房伺服器中,使用者請求進從最近的CDN節點獲取。主要快取圖片、js及css檔案,CDN需要付費,有些規模的網站才會使用。

NGINX快取:對客戶已經訪問過的內容在Nginx伺服器本地建立副本,達到減少Nginx伺服器與後端伺服器之間的網路流量。

應用快取:在後端應用中使用快取,如java常使用Ehcache及gauva快取元件進行資料快取,也可以針對特殊場景在請求中進行執行緒快取。適合呼叫量大且應用內部方法間呼叫,減少網路消耗。

統一快取:使用記憶體減少對資料庫的直接訪問,提高網站效能,如使用memcache或redis搭建快取服務。

前四類都是在網路傳輸中進行資料快取,一般研發很少會去使用,後兩類在應用中快取,在開發中經常使用,接下來介紹後兩類快取的實踐案例。

實踐案例

1、熱點key

場景:在大促期間,給所有活動頁及頻道頁提供側滑html片段資料,會有修改。

特點:資料記錄少,呼叫量比較大(峰值400萬/分鐘)。

在接到需求時,第一反應是使用redis進行快取,資料更新時刪除redis快取。讀取時先讀取redis,快取為空,讀取DB並存放redis。

該場景是使用redis當快取使用,存在一定風險:由於資料量少併發高時,成為熱點key會集中命中單個redis例項,流量上去後,效能會變差,甚至可能拖垮例項。

進一步改進本地JVM快取,加redis快取,JVM快取一分種失效,回源redis及資料庫。存在集中穿透快取回源資料庫,拖垮應用或資料庫的情況,之前有過快取失效,集中回源資料庫的經歷,結果應用服務一臺臺全部倒下,資料庫沒有壓力。事後分析,資料庫配置最大連線數為10,外部請求超時時間為500ms,不斷有新請求進來,大量請求在等待連線。最後選擇在JVM使用ConcurrentMap存放當DB使用,1分鐘非同步重新整理資料。

在大促當天,頁面該請求返回效能不太理想,資料返回大概73KB,使用Nginx增加gzip壓縮後,資料壓縮到13KB,效能提高不少。後續在Nginx增加代理快取,效能穩定。

2、類目中心設計

類目是電商領域最基礎的資料,使用依賴的系統很多,早期是各個系統直接從資料庫讀取並自行快取使用,人為給資料庫增壓。為了避免該情況,著手搭建類目中心,對效能及穩定要求極致,類目中心服務異常不能影響使用方,類目更新後要及時同步給使用方。

經過多次討論,確認使用三級快取:客戶端快取、類目系統jvm快取及統一redis快取。

▲類目中心–讀

客戶端快取:在對外提供的api依賴包中進行快取封裝,通過呼叫類目系統介面提供快取後的服務方法。快取資料記錄失效時間,呼叫時發現快取資料已失效時,更新失效時間並返回,非同步請求類目中心資料重新整理。若快取沒有命中,回源請求類目中心。客戶端會定時檢測類目版本資訊,若版本更新變化,客戶端資料強制更新。

類目系統jvm快取:使用jvm快取,若有過期非同步回源,統一快取redis,穿透直接回源redis。

統一快取redis:當DB使用,不回源資料庫,並定時從資料庫把資料重新整理至redis中。為了避免併發重新整理,使用redis實現排它鎖,保證只一個任務重新整理。

資料更新請求,有一定的規則:

更新資料庫,保證資料庫是正確資料,後續步驟異常也可通過定時全量更新彌補;

更新redis快取;

更新類目中心所有例項JVM快取:由於系統是多例項叢集,需要通知所有例項更新JVM快取;

更新版本號,用於客戶端查驗強制更新標識。一定需要JVM更新完成之後,否則客戶端可能獲取到更新前的“錯誤”資料。

▲類目中心–更新

客戶端95%的請求被客戶端快取命中,呼叫次數3700萬/分鐘,效能TP999為1ms。

▲客戶端呼叫次數

▲客戶端效能

服務端請求次數3000萬/分鐘也沒有壓力,單例項現實際呼叫次數150萬/分鐘。

▲服務端呼叫次數

最後

快取不僅能當快取,也可以當DB使用,避免穿透

資料的更新分主動快取及被動快取

需要解決資料的一致性及有效性

如何使用,怎麼組合,快取什麼資料,都需要結合業務場景,也需要一步步觀察、總結才能優化。

歡迎工作一到五年的Java工程師朋友們加入Java填坑之路:860113481
群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用”沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!
 


相關文章