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:null
無底洞優化
- 無底洞現象
- 分佈式存儲隨着節點數的增長以及key的隨機分佈,批量操做的網絡傳輸次數怎加形成性能不增反減
- 優化方法
- 串行IO
- 先將批量查詢的key所在的節點作mapping
- 屬於相同節點的key合併一組,循環的全部組進行查詢
- 並行IO
- 對串行IO做多線程處理
- hash tag
- 將相同hash tag的數據存儲在同一個節點
- 一次批量查詢只操做相同hash tag的key
- 容易產生數據分佈不均衡
- 串行IO
緩存重建優化
- 問題
- 高併發的熱點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真的必要麼?
- 不一樣的業務模塊建立不一樣的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,仍是必須統一配置
- 不一樣的業務模塊建立不一樣的Cache實例,能夠保持業務模塊獨立性
- 不方便的地方
- 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
- 配置服務化[不推薦]