说说缓存穿透、击穿、雪崩的区别及如何避免

大家好,今天我们一起聊聊Java开发中缓存使用常见的缓存穿透、击穿及雪崩。

大纲

说说缓存穿透、击穿、雪崩的区别及如何避免

Java开发中的缓存

在Java开发中,缓存是指将数据存储在内存中以便快速访问的数据结构或组件。它用于减少对原始数据源的访问次数,从而提高应用程序的性能和响应速度。缓存通常用于存储那些读取频繁但不经常变化的数据。

为什么要使用缓存

性能提升

缓存可以减少对数据库、文件系统或其他慢速数据源的访问,从而显著提高应用程序的性能。

减轻后端压力

当多个用户或系统组件同时请求相同的数据时,缓存可以减少对后端系统的负载,防止其过载。

减少网络延迟

对于分布式系统或微服务架构,缓存可以减少网络调用的次数,从而降低网络延迟。

提高用户体验

快速响应和流畅的用户界面是提高用户满意度和留存率的关键因素,缓存可以帮助实现这一点。

都有哪些缓存技术

Guava Cache

Google开源的Java库,提供了本地缓存的实现,支持自动加载、过期、移除等特性。

Caffeine

一个高性能的Java本地缓存库,提供了基于LRU(最近最少使用)算法的缓存淘汰策略,以及灵活的缓存配置。

Ehcache

一个广泛使用的Java缓存框架,支持在JVM和集群中缓存数据。

JCache (JSR-107)

Java平台的缓存API标准,提供了统一的缓存操作接口,使得开发者可以更容易地切换不同的缓存实现。

Redis

虽然Redis是一个独立的内存数据存储系统,但它经常与Java应用程序一起使用作为缓存层。Redis支持多种数据结构,并提供了丰富的操作命令,非常适合作为分布式缓存解决方案。

Memcached

一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。

Hazelcast

一个开源的Java内存数据网格,提供了分布式缓存、计算、消息传递等功能。

如何选择缓存

在选择缓存技术时,需要考虑应用程序的需求、数据量、访问模式、数据一致性要求以及系统的扩展性等因素。

例如,对于需要分布式缓存的场景,Redis或Hazelcast可能是更好的选择;而对于简单的本地缓存需求,Guava Cache或Caffeine可能更为合适。

缓存的使用中,也会遇到一些问题,特别是缓存穿透缓存击穿缓存雪崩,在使用缓存时,应充分考虑分析,最大限度的避免这三种问题。

缓存穿透

缓存穿透是指查询一个不存在的数据,由于缓存也没有该数据,因此每次请求都会直接打到数据库上,而数据库也没有该数据。这样就造成了缓存和数据库都没有起到应该有的作用,每次请求都要去数据库查询。

图解

说说缓存穿透、击穿、雪崩的区别及如何避免

解决策略

缓存空对象

当一个不存在的数据请求过来时,缓存层不直接返回null,而是缓存一个空对象。但这个空对象也需要设置一个较短的过期时间,防止数据长时间占用缓存。

布隆过滤器

布隆过滤器是一种数据结构,它利用位数组来表示集合,并允许一定的误判率。通过布隆过滤器,可以快速地判断一个请求的数据是否存在于数据库中,从而避免不必要的数据库查询。

集合过滤

采用缓存集合替代缓存单个对象的方式。

当表内数据量不大,需要根据特定条件做过滤后,判断数据是否合法或获取单条数据时,可采用此种策略,只需确保获取集合的sql语句一定可以查出至少一条记录即可。

此方式是一种有效消除缓存穿透的推荐策略。

缓存击穿

缓存击穿是指某个热点数据(key非常热点)过期时,由于并发用户特别多同时读缓存没读到数据,都去数据库查询,引起数据库压力瞬间增大,造成过多请求直接打到数据库上。

图解

说说缓存穿透、击穿、雪崩的区别及如何避免

与缓存穿透的区别

缓存穿透是查询不存在的数据导致的问题;缓存击穿则是查询的数据存在,但因热点数据过期导致的问题

解决策略

互斥锁

使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。

永远不过期

没有设置过期时间,所以不会出现热点key过期后产生的问题。但这也带来了另外的问题,就是缓存的数据如何更新?此时可以通过消息队列来更新缓存,或者定期使用线程池来更新缓存。

缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求直接打到数据库上,瞬间压垮数据库。这通常是由于缓存过期时间设置不当或者缓存服务出现故障导致的。

图解

说说缓存穿透、击穿、雪崩的区别及如何避免

与缓存击穿的区别

缓存击穿是单个或少量热点数据(key)失效;缓存雪崩则是大量缓存同时失效。

缓存击穿对应用服务的感知较小;缓存雪崩可导致应用服务不可用。

解决策略

缓存预热

在系统启动或者低峰时,将热点数据预先加载到缓存中,避免在系统高峰时请求直接打到数据库上。

分布式缓存

使用Redis集群等分布式缓存系统,避免单点故障,提高系统的可用性和容错能力。

降级策略

当缓存系统出现问题时,可以启动降级策略,比如返回默认数据或者提示用户稍后重试,以减轻对数据库的压力。

三者之间的区别

发生场景

缓存击穿是热点数据过期导致的问题;

缓存穿透是查询不存在的数据导致的问题;

缓存雪崩则是大量缓存同时失效或缓存服务故障导致的问题。

影响范围

缓存击穿和缓存穿透通常影响的是单个或多个特定的数据请求;而缓存雪崩则可能影响整个系统的性能和稳定性。

解决策略

虽然三者都可以通过一些通用的策略进行缓解,如使用互斥锁、缓存预热等,但针对每种问题的特定场景和原因,还需要采取更具体的解决策略。

总结

缓存是在Java开发中,提升应用服务性能必不可少的策略,常用的缓存,有本地应用服务缓存和redis缓存,为了使更新后的数据能及时被使用,一般会给缓存设置一定的有效期,设置了有效期的缓存,可能会存在缓存击穿和缓存雪崩的情况,而查询数据库不存在的数据时,又会引起缓存穿透的问题。在详细了解了缓存使用时存在缓存问题的原因后,可以分别针对不同的问题,采用不同的策略,来避免或降低缓存问题对系统性能的影响,从而确保应用服务的高可用性。

点击这里给我留言吧

原文始发于微信公众号(扬哥手记):说说缓存穿透、击穿、雪崩的区别及如何避免

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/263215.html

(0)
葫芦侠五楼的头像葫芦侠五楼

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!