Java接口性能优化万金油之缓存

介绍

缓存在程序开发中被广泛使用,是一种空间换取时间的解决方案,将常用数据存储到高性能存储介质上,当有请求发送到服务端时,优先从缓存中获取数据,如果没有缓存再从数据持久层获取,由于从缓存中读取效率更高,从而极大的提高服务性能,服务响应速度会变得更快。后面会以redis为例,讲解缓存中常见的一些问题和解决方案。

1、缓存穿透

1.1 什么是缓存穿透

当查询一个数据时无法从缓存中获取数据,从而需要查询数据库,同时数据库中也没有该数据,导致无法将数据放入缓存,以至于每个请求过来都需要查询数据库。这种情况下每次查询都需要去访问数据库,缓存没有起到作用即为缓存穿透;

1.2 解决缓存穿透

1.、定义空值,最为简单粗暴的方法就是在缓存中将该数据定义为空,需要注意的是为了保证数据一致性,这些缓存key必须存在更新方式,如设置过期时间等,防止后面该数据真实存在,导致数据不一致;
2、参数校验,为了预防恶意请求,可以对key值做检验,如查询学生信息,合法的学号必须以XH开头,如果用户传入非XH开头的学号如XS1234则直接将该请求拦截,避免因恶意请求导致的缓存穿透;

2、缓存击穿

2.1 什么是缓存击穿

缓存击穿和缓存穿透类似,如果数据库中不存在该数据则为缓存穿透,如果数据库中存在该数据则为缓存击穿,简而言之就是某个缓存失效,导致大量请求同时去访问数据库导致的问题;

2.2 解决缓存击穿

1、提前更新,出现缓存击穿问题是由于缓存过期了导致的,那么为了解决这个问题,我们在缓存过期之前更新缓存信息,保证缓存不过期就可以了,比如一个缓存的过期时间为5分钟,那么我们可以设置一个定时任务每隔4分钟执行一次去更新缓存信息,更新完成后过期时间刷新为5分钟,这样就可以保证缓存不会过期;
2、访问加锁,数据库压力过大的原因就在于同一时刻大量的访问数据库,所以为了解决缓存击穿导致的性能问题,我们需要限制在缓存失效时只能有一个请求可以访问该缓存对应的数据信息!那么我们可以通过加锁的方式去实现上述功能。在访问数据库时加锁,防止多个请求相同数据的请求通过时访问数据库,同时当请求从数据库中查询到结果后再将数据更新到缓存中。
3、消息队列,解决思路和数据库加锁类似,由于消息队列先进先出的特性,从而保证在缓存失效后第一个请求访问数据库后会将最新数据存在缓存中,从而解决缓存击穿问题。
4、永久有效,对于常用但是短时间内不做变更的数据可以不设置过期时间,让其永久有效,从而避免缓存击穿。

3、缓存雪崩

3.1 什么是缓存雪崩

缓存雪崩即出现大量的缓存击穿或者缓存服务器直接崩了导致缓存不可用,大量请求直接访问数据库导致性能下降甚至崩溃;

3.2 如何解决缓存雪崩

1、随机过期,为了防止大量热门缓存同时失效,导致大量请求同时去访问数据库,使得数据库压力大增从而影响服务性能,我们可以对不同缓存设置不同的过期时间,如在实际过期时间后加上一个30秒以内的随机时间。这样的话即使在高并发的情况下也不会出现大量热门缓存同时失效的情况;
2、高可用,为了防止缓存服务崩了导致缓存雪崩,需要对其做高可用设计,如使用哨兵模式,将缓存服务器设置为一主多从,在单个节点出故障后可以有别的节点继续提供服务,避免单个节点故障后整个redis服务不可用的情况;
3、削峰填谷,如果以上措施都失效时为了保证服务不会因为数据库压力崩溃,我们可以通过消息队列对请求进行削峰填谷,保证高并发情况下服务可用性。

4、数据一致性

4.1 什么是数据一致性问题

使用缓存,数据源就涉及数据库和缓存这两部分,因为是两个数据源那么在数据更新时必然会有数据一致性问题。比如我们更新一个学生信息,先更新了 缓存,结果因为某些原因数据库未更新成功,那么数据库数据和缓存数据就不一致了;又比如缓存服务器临时崩溃只更新了数据库数据,那么后面缓存服务器恢复后缓存也还是旧数据;类型的情况有很多,哪门我们要如何保证数据一致性呢?以下从三个方面解决数据一致性问题。

4.2 如何保证数据一致性

1、定时删除,如果是对数据实时性并不是太高的话,可以设置缓存失效时间,缓存失效后再从数据库获取最新数据并写入缓存;
2、数据双删,为了避免数据库更新数据时其他线程获取到旧的数据缓存,我们可以在更新数据库数据前先将缓存数据删除,在更新数据库完成后将缓存再删除一次保证后面的缓存和数据库数据是一致的!具体实现可以看redis缓存双删案例讲解

注:对缓存的操作建议直接删除而不是对缓存数据做更新,因为如果是更新的话每次数据变更都要对缓存进行操作,而如果是删除的话,只要该数据没被在重新使用,就只要进行一次操作了!!比如我们变更一个学生信息,如果10分钟内我们更新了20次,使用更新的话那么对缓存的操作也是要更新20次。如果直接删除缓存,只要用户没有再调用这个学生信息,那么我们只要删除一次缓存即可,因为删除后缓存已经不存在了

猜你喜欢

转载自blog.csdn.net/xianren95/article/details/126598955
今日推荐