Cache架构设计
Cache策略
- 定時過期策略
- 定時過期的好處是Cache節點的個數符合實際需求,不會造成資源濫用和服務器壓力
- 定時過期適合訪問量較大,實時性要求不高的情況
- 如果訪問量小,定時過期會造成Cache命中率低,如果實時性要求高,過期間隔太小,Cache的意義就不大
- 適用情況 : 實時性低
- 全量刷新策略
- 全量刷新的好處是Cache命中率高,Cache實時性高
- 全量數據相比那些Cache key值設置不好的非全量Cache,可能反而更小
- 全量刷新的弊端是有可能造成服務器的壓力,如果數據使用率低,就是對資源的濫用
- 全量刷新適合數據量小或者數據使用率高的應用
- 適用情況 : 數據量小
- 定時刷新策略
- 定時刷新的Cache節點個數和Cache大小成正比,需要綜合考慮Cache命中率和數據量設定節點個數
- 節點數過大會造成Cache龐大,過小會造成命中率低
- 定時刷新的頻率和實時性成正比
- 定時刷新對服務器資源有一定的濫用
- 需要開發人員了解具體服務的訪問量數據量,制定合適的節點個數與刷新頻率
- 使用情況 : 其他策略無法滿足
- 定時過期+磁盤持久化策略
- 過期Cache存磁盤文件,系統下線所有cache持久化
- 分布式Cache機制,互相備份,錯開重啟
- 可以在一定條件下舍棄數據庫
- Cache與訪問量,數據量,定時性的關系
- 訪問量大,數據量大,實時性高,可以使用復雜的定時刷新,還需要根據實際情況做優化
- 訪問量小,數據量大,實時性高,可以使用定時刷新或不用Cache
- 數據量小,實時性高,可以使用全量刷新
- 訪問量大,數據量大,實時性低,可以使用定時過期
- 訪問量小,數據量大,實時性低,可以使用定時過期或者定時刷新
智能Cache策略
- UserPreference cache
- Subscription cache
- 分時間段的Cache,某些時間段的某些cache不過期,需要通過分析流量制定時間段
穿透優化
- 緩存穿透
- 發生大量不存在的key的訪問,會加重對數據庫層的壓力
- 優化方法
- 緩存空對象key:null
- 空對象使用一個比較短的過期時間
- 用主動刷新策略應對key又被存入數據庫的情況
- 實現成本低,占用內存不可控(由非法key和合法key的比例決定)
- 布隆過濾器攔截
- BloomFilter緩存所有存在的key,進行第一層過濾
- 會降低緩存的性能,實現成本高,占用內存可控
- 不使用傳統的低性能的數據庫
無底洞優化
- 無底洞現象
- 分布式存儲隨著節點數的增加以及key的隨機分布,批量操作的網絡傳輸次數怎加造成性能不增反減
- 優化方法
- 串行IO
- 先將批量查詢的key所在的節點做mapping
- 屬于相同節點的key合并一組,循環的所有組進行查詢
- 并行IO
- 對串行IO作多線程處理
- hash tag
- 將相同hash tag的數據存儲在同一個節點
- 一次批量查詢只操作相同hash tag的key
- 容易產生數據分布不均衡
緩存重建優化
- 問題
- 高并發的熱點key+數據對象大重建緩慢
- 數據過期等情況造成大量線程來重建緩存,使得服務崩潰
- 優化方法
- 永不過期或者timeToIdle+主動更新
- 互斥鎖:Redis可以用setnx實現
- 用戶請求不重建緩存,用單獨線程合并用戶請求重建緩存
熱點key集中化優化
其他等待解決疑問
- Server resource的個數大小如何定
- resourcePool的個數與大小
- Manage the CacheManager/Cahce/Entity
- load balance
- Thread Pools線程池
- key生成策略
CacheManager/Cache等實例數量與大小的考慮
- server resource & resource pool
- server resource可以多設置幾個,比如每個1-5G這樣,設置5個備用,每個可以給一個CacheManager使用
- 一個server resource里可以設置一個或多個resourcePool用于clusteredShared,一個或多個resourcePool用于clusteredDedicated,這個要根據實際需求
- 一旦clusted端建立了CacheManager,此CacheManager所占用的resourcePool就會被分配給這個CacheManager,所以resourcePool的大小應該更具項目實際情況設置,以免造成資源浪費
- 一個pool滿了,就使用下一個,而不是增加它的大小,不然會影響所有使用者
- 也可以使得pool的大小動態獲取,而不是hard code
- CacheManager
- 不同的業務模塊創建不同的CacheManager實例,可以保持業務模塊獨立性
- 比如說可以單獨清除一個CacheManager的所有Cache
- 多個CacheManager,配置代碼在不同項目的復用會出現問題,如何解決?
- 用一個項目創建CacheManager,其他項目用缺省的方式連接CacheManager
- 單個CacheManager和多個CacheManager的性能問題?多個CacheManager真的必要么?
- Cache
- 不同的業務模塊創建不同的Cache實例,可以保持業務模塊獨立性
- 不同的業務模塊可以使用不同的key規則
- 可以獨立的管理cache,比如刪除等操作
- 可以更合理的定制Cache大小,提高cache命中率
- 可以更合理的定制Expiry
- 通過不同的Expiry策略創建不同的Cache實例
- 方便開發,無須每次都創建新的cache
- clusteredDedicated
- 必須指定cache的大小,不適合producer/consumer的方式,因為consumer必須知道producer設置的大小
- 能夠更好的更具實際需要利用內存資源
- clusteredShared
- 不需要指定每個cache大小,方便producer/consumer主從互換
- Shared pool的大小必須足夠大,而且基本不變,才能方便使用,這樣便會造成內存的浪費
- Shared pool的變化會造成所有producer/consumer的配置要變
- clustered繼承
- 解決了clusteredDedicated的問題
- 但是如果有兩個以上的producer或者spring cache那樣自己也是producer,還是必須統一配置
- 不方便的地方
- spring cache無須手動create cache,但是ehcache clustered必須手動,因為每個cache的配置更靈活
- withCache/createCache創建新cache,必須用autoCreate,在原來的CacheManager實例里創建新的cache并且連接
- 動態cache配置機制
- 多個Cache不同項目的配置
- 配置服務化[不推薦]
- 將配置信息封裝成配置對象
- service提供獲取配置對象服務
- 造成client項目依賴service或者cache項目
- 主從互換
- service與client都去判斷cluster端是否存在cache,如果不存在,那么創建,否則繼承
- 造成cache manage也無法繼承
- 無法保證service與client創建cache時使用相同配置
- 適合clusteredShared
- 不適合clusteredDedicated的原因是client必須知道service端設置的大小
- 如果有兩個以上的producer,也不適合clustered繼承
- 完美主從互換[跨項目組的情況下建議使用]
- 方法1: service提供Cache配置服務,client獲取配置創建cache,配置服務使得service必須有服務提供
- 方法2: common jar的形式保證創建cache時使用相同配置
- 方法3: service方提供client代碼,client利用client代碼創建cache
- 保證service與client創建cache時使用相同配置
- service必須知道自己的cache的配置,無法使用動態cache配置機制
- 需要動態cache配置的時候只適合clusteredShared,否則可以使用clusteredDedicated
- 這個工作需要額外開發,很麻煩啊,兩害取其輕,還是使用clusteredShared+動態pool size吧,一點點浪費總比不可控也增加開發/維護難度好
- service主導[不推薦]
- client判斷cluster端是否存在cache,如果不存在,那么創建,否則繼承
- service判斷cluster端配置是否符合自己要求,如何不符合,刪除cache重新創建,否則直接創建
- 但是必須所有cache manager close()
- 適合clusteredDedicated
轉載于:https://www.cnblogs.com/judesheng/p/10649391.html
總結
- 上一篇: Mysql在字符串类型的日期上加上10分
- 下一篇: tvnewpro 病毒清除