系統性能提升優先法寶 | 緩存應用實踐
緩存是系統性能提升優先法寶,在互聯網應用系統中,屢試不爽。網上有很多資料介紹緩存理論及使用策略,本文就不再涉及了,今天簡單將緩存做個歸類,重點分享以前在實際業務中碰到場景以及如何使用。
接下來主要分兩部分介紹:緩存分類與應用實踐案例。
緩存分類
緩存一般有以下幾類:客戶端、瀏覽器、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緩存。
(1) 類目中心--讀
- 客戶端緩存:在對外提供的api依賴包中進行緩存封裝,通過調用類目系統接口提供緩存后的服務方法。緩存數據記錄失效時間,調用時發現緩存數據已失效時,更新失效時間并返回,異步請求類目中心數據刷新。若緩存沒有***,回源請求類目中心。客戶端會定時檢測類目版本信息,若版本更新變化,客戶端數據強制更新。
- 類目系統jvm緩存:使用jvm緩存,若有過期異步回源,統一緩存redis,穿透直接回源redis。
- 統一緩存redis:當DB使用,不回源數據庫,并定時從數據庫把數據刷新至redis中。為了避免并發刷新,使用redis實現排它鎖,保證只一個任務刷新。
數據更新請求,有一定的規則:
- 更新數據庫,保證數據庫是正確數據,后續步驟異常也可通過定時全量更新彌補;
- 更新redis緩存;
- 更新類目中心所有實例JVM緩存:由于系統是多實例集群,需要通知所有實例更新JVM緩存;
- 更新版本號,用于客戶端查驗強制更新標識。一定需要JVM更新完成之后,否則客戶端可能獲取到更新前的“錯誤”數據。
(2) 類目中心--更新
客戶端95%的請求被客戶端緩存***,調用次數3700萬/分鐘,性能TP999為1ms。
(3) 客戶端調用次數
(4) 客戶端性能
服務端請求次數3000萬/分鐘也沒有壓力,單實例現實際調用次數150萬/分鐘。
(5) 服務端調用次數
***
- 緩存不僅能當緩存,也可以當DB使用,避免穿透
- 數據的更新分主動緩存及被動緩存
- 需要解決數據的一致性及有效性
如何使用,怎么組合,緩存什么數據,都需要結合業務場景,也需要一步步觀察、總結才能優化。
【本文來自51CTO專欄作者張開濤的微信公眾號(開濤的博客),公眾號id: kaitao-1234567】