当前位置: 首页 > 图灵资讯 > 技术篇> 你管这破玩意叫缓存穿透?还是缓存击穿?

你管这破玩意叫缓存穿透?还是缓存击穿?

来源:图灵教育
时间:2023-05-15 09:27:12

一、缓存预热

Redis缓存预热是指在服务器启动或应用程序启动前将一些数据存储到Redis中,以提高Redis的性能和数据一致性。这可以减少服务器在启动或应用程序启动时的数据传输和延迟,从而提高应用程序的性能和可靠性。

1、常见的缓存预热步骤

(1)数据准备

在应用程序启动或服务器启动之前,准备静态数据、缓存数据或其他需要预热的数据。

(2)数据存储

在Redis中存储数据,可以使用Redis列表(List)数据类型或集合(Set)数据类型。

(3)数据预热

在服务器启动或应用程序启动之前,将数据存储到Redis中。此操作可以使用Redis的客户端工具或命令行工具进行。

(4)数据清洗

服务器启动或应用程序启动后,存储在Redis中的数据可能会被清理和处理。例如,可以删除过期数据、修改错误数据等。

需要注意的是,Redis缓存预热可能会增加服务器的成本,因此应在必要时进行。同时,为了减少预热次数,可以考虑使用其他类型的Redis数据,如哈希表(Hash)或有序集合(Sorted Set)。此外,为了提高数据的一致性和性能,Redis可以使用Redis的持久功能将数据存储在Redis中,并在服务器重启后自动恢复数据。

2、代码实现
@Component@Slf4jpublic class BloomFilterInit{    @Resource    private RedisTemplate redisTemplate;    ///初始化白名单数据    @PostConstruct    public void init() {        //1 白名单客户加载布隆过滤器        String key = "customer:1";        //2 计算hashvalue,由于计算负数的可能性,我们取绝对值        int hashValue = Math.abs(key.hashCode());        //3 hashvalue和2的32次方后取余,获取相应的下标坑        long index = (long)(hashValue % Math.pow(2,32));        log.info(key+" 相应的坑位index:{}",index);        //4 在redis中设置bitmap对应类型的白名单:whitelistcustomer的坑位,并将该值设置为1        redisTemplate.opsForValue().setBit("whitelistCustomer",index,true);    }}
二、缓存雪崩

Redis缓存雪崩是指由于某些原因,缓存数据突然被删除或修改,导致缓存系统性能下降,甚至无法正常工作。

1、缓存雪崩发生在什么情况下?

(1)误删除

缓存系统可能会因误操作或故障而误删除一些正常数据。这种情况通常发生在数据库中。

(2)误修改

缓存系统可能会因误操作或故障而误修改一些正常数据。这通常发生在数据库中。

(3)负载波动

缓存系统通常会承受一定的负载波动,例如,在高峰期,数据量可能会显著增加,从而导致缓存系统性能下降。

(4)数据变化频繁

如果缓存系统中的数据变化频繁,例如,每秒都会有大量的数据插入或删除,那么缓存系统可能会因响应缓慢而导致雪崩。

2、Redis缓存集群实现高可用性

(1)主从 + 哨兵

(2)Redis集群

(3)开启Redis持久机制aof/rdb,尽快恢复缓存集群。

3、如何避免Redis缓存雪崩?

(1)数据备份

定期备份数据,防止误删或误修改。

(2)数据同步

定期同步数据,防止数据不一致。

(3)负载平衡

使用负载均衡器将请求分配到多个Redis实例中,以减少单个实例的负载。

(4)数据优化

优化数据库结构,减少频繁的数据变化。

(5)监控和报警

监控Redis实例的性能指标,及时发现缓存系统异常,并发出报警。

三、缓存穿透

Redis缓存穿透是指由于某些原因,Redis缓存系统中的缓存数据无法正常访问或处理,导致缓存失去其功能。

1、缓存穿透会发生什么?

(1)数据量过大

当缓存中存储的数据量过大时,缓存的数据量可能会超过Redis的数据存储限制,导致缓存失去其功能。

(2)数据更新频繁

当缓存中存储的数据更新频繁时,缓存的数据可能会异步变化,导致缓存无法正常访问。

(3)数据过期

当存储在缓存中的数据过期时,缓存数据可能会失去其功能,因为Redis会在一段时间后自动删除过期数据。

(4)数据权限限制

当缓存中存储的数据受到权限的限制时,只有有足够权限的用户才能访问和处理这些数据,导致缓存失去其功能。

(5)Redis性能瓶颈

当Redis服务器的性能达到极限时,Redis缓存可能会因响应缓慢而穿透。

2、如何避免Redis缓存穿透?

(1)设置合理的缓存大小

根据实际需要设置合理的缓存尺寸,避免缓存穿透。

(2)优化数据结构

为了减少数据的大小和更新频率,根据实际需要优化数据结构。

(3)设置合理的过期时间

为避免缓存失去其作用,设置合理的过期时间。

(4)增加Redis的并发处理能力

通过提高Redis的并发处理能力,提高缓存处理能力和响应速度。

(5)优化Redis服务器的硬件和软件配置

通过优化Redis服务器的硬件和软件配置,提高Redis的性能和处理能力。

你管这破玩意叫缓存穿透?还是缓存击穿?_缓存

四、缓存穿透通过空对象缓存解决

如果发生缓存穿透,可以在Redis中插入数据,添加约定的默认值,如defaultnull。

比如你想通过某个id查询某个订单,Redis中没有,MySQL中没有。这个时候可以在Redis中插入一个,存储为defaultNull,下次再查询。因为是提前约定的,前端也知道是什么意思。一切都好,岁月静。

这样只能解决key相同的情况,如果key不同,那就完蛋了。

Guava,Google布隆过滤器,缓存穿透

你管这破玩意叫缓存穿透?还是缓存击穿?_数据_02

1、引入pom
<!--guava Google 开源的 Guava 自带布隆过滤器--><dependency>    <groupId>com.google.guava</groupId>    <artifactId>guava</artifactId>    <version>23.0</version></dependency>
2、创建布隆过滤器
BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100);

(3)在布隆过滤器中添加元素

bloomFilter.mightContain(1)

(4)判断布隆过滤器是否存在

bloomFilter.mightContain(1)
3、fpp误判率
@Service@Slf4jpublic class GuavaBloomFilterService {    public static final int SIZE = 1000000;    //误判率    public static double fpp = 0.01;    ///创建guava布隆过滤器    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE, fpp);        public void guavaBloomFilter() {        for (int i = 1; i <= SIZE; i++) {            bloomFilter.put(i);        }        ArrayList<Integer> list = new ArrayList<>(10000);        for (int i = SIZE + 1; i <= SIZE + (10000); i++) {            if (bloomFilter.mightContain(i)) {                log.info("误判:{}" i);                list.add(i);            }        }        log.info(误判总数:{} list.size());    }}
六、Redis缓存击穿

Redis缓存击穿是指由于某些原因,Redis缓存系统中的缓存数据无法正常访问或处理,导致缓存失去其功能。

1、缓存击穿会发生什么?

热点Key失败的根本原因。

(1)数据量过大

当缓存中存储的数据量过大时,缓存的数据量可能会超过Redis的数据存储限制,导致缓存失去其功能。

(2)数据更新频繁

当缓存中存储的数据更新频繁时,缓存的数据可能会异步变化,导致缓存无法正常访问。

(3)数据过期

当存储在缓存中的数据过期时,缓存数据可能会失去其功能,因为Redis会在一段时间后自动删除过期数据。

(4)数据权限限制

当缓存中存储的数据受到权限的限制时,只有有足够权限的用户才能访问和处理这些数据,导致缓存失去其功能。

(5)Redis性能瓶颈

当Redis服务器的性能达到极限时,Redis缓存可能会因响应过慢而击穿。

2、如何避免Redis缓存击穿?

(1)设置合理的缓存大小

根据实际需要设置合理的缓存尺寸,避免缓存穿透。

(2)优化数据结构

为了减少数据的大小和更新频率,根据实际需要优化数据结构。

(3)设置合理的过期时间

为避免缓存失去其作用,设置合理的过期时间。

(4)增加Redis的并发处理能力

通过提高Redis的并发处理能力,提高缓存处理能力和响应速度。

(5)优化Redis服务器的硬件和软件配置

通过优化Redis服务器的硬件和软件配置,提高Redis的性能和处理能力。

7.Redis缓存击穿解决方案1、互斥更新

通过双检加锁机制。

2、差异失效时间

你管这破玩意叫缓存穿透?还是缓存击穿?_缓存_03

首先从缓存B更新,然后更新主缓存A,并使缓存B的缓存失效时间长于A,以确保B仍然存在。