Cache架构设计

Cache策略

  • 定时过时策略
    1. 定时过时的好处是Cache节点的个数符合实际需求,不会形成资源滥用和服务器压力
    2. 定时过时适合访问量较大,实时性要求不高的状况
    3. 若是访问量小,定时过时会形成Cache命中率低,若是实时性要求高,过时间隔过小,Cache的意义就不大
    4. 适用状况 : 实时性低
  • 全量刷新策略
    1. 全量刷新的好处是Cache命中率高,Cache实时性高
    2. 全量数据相比那些Cache key值设置很差的非全量Cache,可能反而更小
    3. 全量刷新的弊端是有可能形成服务器的压力,若是数据使用率低,就是对资源的滥用
    4. 全量刷新适合数据量小或者数据使用率高的应用
    5. 适用状况 : 数据量小
  • 定时刷新策略
    1. 定时刷新的Cache节点个数和Cache大小成正比,须要综合考虑Cache命中率和数据量设定节点个数
    2. 节点数过大会形成Cache庞大,太小会形成命中率低
    3. 定时刷新的频率和实时性成正比
    4. 定时刷新对服务器资源有必定的滥用
    5. 须要开发人员了解具体服务的访问量数据量,制定合适的节点个数与刷新频率
    6. 使用状况 : 其余策略没法知足
  • 定时过时+磁盘持久化策略
    1. 过时Cache存磁盘文件,系统下线全部cache持久化
    2. 分布式Cache机制,互相备份,错开重启
    3. 能够在必定条件下舍弃数据库
  • Cache与访问量,数据量,定时性的关系
    1. 访问量大,数据量大,实时性高,可使用复杂的定时刷新,还须要根据实际状况作优化
    2. 访问量小,数据量大,实时性高,可使用定时刷新或不用Cache
    3. 数据量小,实时性高,可使用全量刷新
    4. 访问量大,数据量大,实时性低,可使用定时过时
    5. 访问量小,数据量大,实时性低,可使用定时过时或者定时刷新

智能Cache策略

  • UserPreference cache
  • Subscription cache
  • 分时间段的Cache,某些时间段的某些cache不过时,须要经过分析流量制定时间段

穿透优化

  • 缓存穿透
    1. 发生大量不存在的key的访问,会加剧对数据库层的压力
  • 优化方法
    1. 缓存空对象key:null
      1. 空对象使用一个比较短的过时时间
      2. 用主动刷新策略应对key又被存入数据库的状况
      3. 实现成本低,占用内存不可控(由非法key和合法key的比例决定)
    2. 布隆过滤器拦截
      1. BloomFilter缓存全部存在的key,进行第一层过滤
      2. 会下降缓存的性能,实现成本高,占用内存可控
    3. 不使用传统的低性能的数据库

无底洞优化

  • 无底洞现象
    1. 分布式存储随着节点数的增长以及key的随机分布,批量操做的网络传输次数怎加形成性能不增反减
  • 优化方法
    1. 串行IO
      1. 先将批量查询的key所在的节点作mapping
      2. 属于相同节点的key合并一组,循环的全部组进行查询
    2. 并行IO
      1. 对串行IO做多线程处理
    3. hash tag
      1. 将相同hash tag的数据存储在同一个节点
      2. 一次批量查询只操做相同hash tag的key
      3. 容易产生数据分布不均衡

缓存重建优化

  • 问题
    1. 高并发的热点key+数据对象大重建缓慢
    2. 数据过时等状况形成大量线程来重建缓存,使得服务崩溃
  • 优化方法
    1. 永不过时或者timeToIdle+主动更新
    2. 互斥锁:Redis能够用setnx实现
    3. 用户请求不重建缓存,用单独线程合并用户请求重建缓存

热点key集中化优化

其余等待解决疑问

  • Server resource的个数大小如何定
  • resourcePool的个数与大小
  • Manage the CacheManager/Cahce/Entity
  • load balance
  • Thread Pools线程池
  • key生成策略

CacheManager/Cache等实例数量与大小的考虑

  • server resource & resource pool
    1. server resource能够多设置几个,好比每一个1-5G这样,设置5个备用,每一个能够给一个CacheManager使用
    2. 一个server resource里能够设置一个或多个resourcePool用于clusteredShared,一个或多个resourcePool用于clusteredDedicated,这个要根据实际需求
    3. 一旦clusted端创建了CacheManager,此CacheManager所占用的resourcePool就会被分配给这个CacheManager,因此resourcePool的大小应该更具项目实际状况设置,以避免形成资源浪费
    4. 一个pool满了,就使用下一个,而不是增长它的大小,否则会影响全部使用者
    5. 也可使得pool的大小动态获取,而不是hard code
  • CacheManager
    1. 不一样的业务模块建立不一样的CacheManager实例,能够保持业务模块独立性
      1. 好比说能够单独清除一个CacheManager的全部Cache
    2. 多个CacheManager,配置代码在不一样项目的复用会出现问题,如何解决?
      1. 用一个项目建立CacheManager,其余项目用缺省的方式链接CacheManager
    3. 单个CacheManager和多个CacheManager的性能问题?多个CacheManager真的必要么?
  • Cache
    1. 不一样的业务模块建立不一样的Cache实例,能够保持业务模块独立性
      1. 不一样的业务模块可使用不一样的key规则
      2. 能够独立的管理cache,好比删除等操做
      3. 能够更合理的定制Cache大小,提升cache命中率
      4. 能够更合理的定制Expiry
    2. 经过不一样的Expiry策略建立不一样的Cache实例
      1. 方便开发,无须每次都建立新的cache
    3. clusteredDedicated
      1. 必须指定cache的大小,不适合producer/consumer的方式,由于consumer必须知道producer设置的大小
      2. 可以更好的更具实际须要利用内存资源
    4. clusteredShared
      1. 不须要指定每一个cache大小,方便producer/consumer主从互换
      2. Shared pool的大小必须足够大,并且基本不变,才能方便使用,这样便会形成内存的浪费
      3. Shared pool的变化会形成全部producer/consumer的配置要变
    5. clustered继承
      1. 解决了clusteredDedicated的问题
      2. 可是若是有两个以上的producer或者spring cache那样本身也是producer,仍是必须统一配置
  • 不方便的地方
    1. spring cache无须手动create cache,可是ehcache clustered必须手动,由于每一个cache的配置更灵活
    2. withCache/createCache建立新cache,必须用autoCreate,在原来的CacheManager实例里建立新的cache而且链接
  • 动态cache配置机制
  • 多个Cache不一样项目的配置
    1. 配置服务化[不推荐]
      1. 将配置信息封装成配置对象
      2. service提供获取配置对象服务
      3. 形成client项目依赖service或者cache项目
    2. 主从互换
      1. service与client都去判断cluster端是否存在cache,若是不存在,那么建立,不然继承
      2. 形成cache manage也没法继承
      3. 没法保证service与client建立cache时使用相同配置
      4. 适合clusteredShared
      5. 不适合clusteredDedicated的缘由是client必须知道service端设置的大小
      6. 若是有两个以上的producer,也不适合clustered继承
    3. 完美主从互换[跨项目组的状况下建议使用]
      1. 方法1: service提供Cache配置服务,client获取配置建立cache,配置服务使得service必须有服务提供
      2. 方法2: common jar的形式保证建立cache时使用相同配置
      3. 方法3: service方提供client代码,client利用client代码建立cache
      4. 保证service与client建立cache时使用相同配置
      5. service必须知道本身的cache的配置,没法使用动态cache配置机制
      6. 须要动态cache配置的时候只适合clusteredShared,不然可使用clusteredDedicated
      7. 这个工做须要额外开发,很麻烦啊,两害取其轻,仍是使用clusteredShared+动态pool size吧,一点点浪费总比不可控也增长开发/维护难度好
    4. service主导[不推荐]
      1. client判断cluster端是否存在cache,若是不存在,那么建立,不然继承
      2. service判断cluster端配置是否符合本身要求,如何不符合,删除cache从新建立,不然直接建立
      3. 可是必须全部cache manager close()
      4. 适合clusteredDedicated
相关文章
相关标签/搜索