缓存雪崩:缓存在同一时间失效时,访问直达数据库层,可能导致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算法移除;