關於web緩存的思考

公司緩存出了些問題,解決的過程當中總結了一些緩存使用的方式方法。html

公司緩存遇到的問題

1) 緩存無過時時間致使內存佔用太高
2) 緩存清除後,失效後仍用到,不可從數據庫恢復前端

形成這些問題的緣由是開發人員對緩存的設計和使用原則不清楚,架構上也沒有明確的說明和引導。數據庫

關於上面的兩個問題

1) 緩存添加時必定要有清除策略。程序狀態完結時主動刪除或者設置合理過時時間,否則就會形成內存泄漏,固然架構層面能夠在內存資源緊張時使用必定策略進行回收,可是被強制清除的緩存如何恢復,可否恢復也是一個須要考慮的問題,正確的作法應該是清除策略和資源回收兩方面同時進行,清除策略爲主,資源回收只能是預防性的工做,資源回收也容易形成問題。另外,正確的監控和統計工做能夠發現異常的緩存key,防止程序錯誤日積月累佔用大量資源突發嚴重問題。
2) 緩存過時或者被錯誤清除仍用到不可從數據庫恢復。緩存清除仍用到是程序設計上的問題形成的,但不可從數據庫恢復涉及緩存數據恢復問題。緩存數據應該是數據庫數據的某種映射,由於緩存是臨時存儲,自己就是不可靠的,數據庫是持久存儲,是可靠的,緩存是爲了加速數據訪問,下降數據庫壓力而存在的,因此緩存數據應該很容易從數據庫恢復,這裏把緩存當作不可恢復的持久存儲用是不對的。若是須要高性能的持久存儲,好比保存程序中間結果,能夠考慮使用Redis等(使用時不須要恢復策略,但也須要清除策略)。簡單的說,緩存做爲非持久性存儲,數據應該是能夠很輕易的從持久存儲恢復的。緩存

那緩存應該怎樣設計和使用呢?

從設計一個網站的緩存角度來考慮能想到的方面,緩存應該分類爲數據庫緩存 (或者說持久存儲,數據都能從DB恢復)、臨時數據緩存(只須要存儲較短期的中間數據,能由持久存儲恢復,但時間較長,好比報表數據)、前端緩存(頁面緩存、頁面片斷緩存、由html加動態數據混合而成,緩存已加快渲染和返回速度),這裏咱們只考慮持久存儲緩存或者簡單的說數據庫緩存。性能優化

數據庫緩存

定義:數據庫緩存是爲了加速數據訪問,減輕DB壓力而存在的一種臨時性高速存儲。架構

1) 緩存添加
什麼樣的數據應該放到緩存裏?訪問頻繁的數據應該放到緩存裏,仍是說爲了提升性能,把大部分數據庫數據放到緩存裏?
從性能優化的角度來講,不該該提早優化,應該是遇到性能問題、性能問題初漏端倪、爲了預防性能問題而使用緩存(最好基於性能測試和監控),因此最開始應該爲預估的熱點數據設置緩存,或者遇到性能問題時爲相關數據添加緩存(設置緩存應該是開發人員的工做,架構方面應提供緩存服務,也能夠經過統一的數據訪問層來實現,若是架構方面能根據熱點數據自動應用緩存最好,多級緩存技術中,靠近底層的的緩存應該是根據預估或者統計的數據熱點手動或自動添加的,更高級的緩存應該是應用程序或者說調用方添加的) 。併發

2) 緩存更新
緩存的更新能夠分爲過時更新和程序主動更新。先更新緩存仍是先更新數據庫?若是先更新緩存後更新數據庫,這樣客戶使用的多是緩存的數據,若是此時出現故障數據庫更新失敗,那麼用戶使用的數據跟數據庫中數據是不對應的,因此要先更新數據庫再更相信緩存,這也印證了數據庫是主存儲,緩存是DB數據的某種映射,是副存儲的設計原則 。要更新數據庫,又要更新緩存,這樣在實時性要求較高的高併發場景下就確定會遇到數據一致性的問題。 對於讀多寫少的需求來講,能夠在寫數據庫後同步更新緩存,這樣除了在實時性要求很是高且併發很高的狀況下才會出現數據不一致的狀況,大多數狀況下都能運行良好。對於實時性要求較低需求來講,只須要設置緩存的過時時間,等待緩存過時後從DB從新加載。對於寫很是頻繁、容忍必定偏差的需求來說,先寫緩存,定時刷回數據庫是一種可行的方案。運維

3) 緩存清除
緩存清除策略是必要的,否則就容易發生內存泄漏的狀況,及時清除緩存也能夠爲新的緩存騰出空間,提升緩存性能。清除策略應該是程序主動清除和過時時間相結合的方式,在程序層面要作清除,在架構層面要作監控、統計和在資源不足時根據必定策略清除,兩方面都要作。高併發

臨時數據緩存

定義:只須要存儲較短期的中間數據。性能

臨時數據緩存要考慮更新策略和清除策略。更新不是問題,直接更新就行,清除策略能夠是主動清除,設置過時時間的話須要明確在過時時間以內不會再次用到該緩存,可是設置過時時間每每不太靠譜,由於臨時數據緩存不像數據庫緩存那樣容易恢復,不設置過時時間因程序bug沒有主動清除緩存會累積垃圾數據,不過能夠經過定時清理功能來清除,但這須要依賴開發與運維協做,可能效率低下,不過因爲程序bug形成累積垃圾數據是不可避免的,按期的開發與運維相配合的架構清理應該也是必要的。

相關文章
相關標籤/搜索