缓存雪崩:缓存在同一时间失效时,访问直达数据库层,可能导致DB挂掉、系统崩溃。
对应方案1:交错缓存失效时间或随机缓存失效时间。
对应方案2:主从热备(Redis sentinel)。
对应方案3:集群/水平切分(Redis Cluster、一致性哈希)。
5.5 缓存穿透
缓存穿透:持续高并发访问某个不存在的Key。
对应方案1:空值缓存。
对应方案2:布隆过滤器(bloom filter) + bitmap。穷举可能访问的数据放入bitmap中,使用hash访问。
5.6 缓存击穿
缓存击穿:热点Key失效,高并发请求,直击数据库。
缓存击穿与缓存穿透很相似,不同点是是缓存击穿前访问的是真实的热点数据,只是在某一刹那失效了,造成了击穿的效果。
这样看,它其实也是缓存雪崩的一个特例。与雪崩的区别即在于击穿是对于特定的热点数据,而雪崩是全部数据。
对应方案:多级缓存及交错失效时间 + LRU 淘汰算法。
对于热点数据进行二级或多级缓存,并对于不同级别的缓存设定不同的失效时间,缓解雪崩。
此外可使用LRU的变种算法LRU-K缓存数据。
5.7 缓存降级
缓存降级是服务降级中的一环。
在访问量剧增,导致服务出现问题时,为了保证核心服务可用,防止发生缓存雪崩,可进行服务降级。
以redis为例,比较常见的做法就是,不去数据库查询,而是直接返回默认值给用户。
缓存降级也可根据日志级别进行预案设置。
6. 分布式缓存的选型
说了这么多缓存的原理与策略,说说我们在实际工作中应该怎么去做缓存选型。
以下就是常用的几种缓存工具。
6.1 Ehcache
Ehcache是纯Java开源的缓存框架,最早从hibernate发展而来,现在算是springboot中的官配缓存工具,整合简单。特点如下:
快速,针对大型高并发系统场景,Ehcache的多线程机制有相应的优化改善;
简单,很小的jar包,简单配置就可直接使用,单机场景下无需过多的其他服务依赖;
支持多种的缓存策略,灵活;
缓存数据有两级:内存和磁盘,与一般的本地内存缓存相比,有了磁盘的存储空间,将可以支持更大量的数据缓存需求;
具有缓存和缓存管理器的侦听接口,能更简单方便的进行缓存实例的监控管理;
支持多缓存管理器实例,以及一个实例的多个缓存区域。
6.2 Guava Cache
Guava Cache是Google开源的Java重用工具集库Guava里的一款缓存工具,特点如下:
自动将entry节点加载进缓存结构中;
当缓存的数据超过设置的最大值时,使用LRU算法移除;