当前位置: 首页 > 科技观察

一位Java大牛分享了几个关于Redis缓存的典型面试题

时间:2023-03-16 01:08:43 科技观察

随着系统访问量和复杂度的增加,响应性能成为重点关注点。而缓存的使用就成为一个重点。Redis作为缓存中间件的佼佼者,已经成为面试必考项目。本文分享Redis的一些常见面试题:CacheAvalanche1.1什么是CacheAvalanche?如果我们的缓存发生故障,则意味着我们所有的请求都转到了数据库。我们都知道Redis无法缓存所有的数据(内存昂贵且有限),因此Redis需要为数据设置一个过期时间,采用惰性删除+定时删除两种策略来删除过期的key。如果缓存数据设置的过期时间相同,Redis只是将这部分数据全部删除。这会导致这些缓存在这段时间内同时失效,所有的请求都会发送到数据库。这就是缓存雪崩:Redis挂了,所有的请求都跑到数据库去了。如果发生缓存雪崩,很可能会把我们的数据库搞垮,让整个服务瘫痪!1.2如何解决缓存雪崩?在缓存的时候给过期时间加上一个随机值,同时会大大减少缓存过期时间。对于“Redis挂了,所有请求都跑到数据库”的情况,我们可以有以下思路:事发前:实现Redis的高可用(主从架构+Sentinel或者RedisCluster),尽量避免使用Redis挂断情况发生。事件过程中:万一Redis真的挂了,我们可以设置本地缓存(ehcache)+限流(hystrix),尽量避免我们的数据库在redis之后被kill掉(至少保证我们的服务还能正常工作)事件:Redis是持久化的,重启后自动从磁盘加载数据,快速恢复缓存数据。缓存穿透2.1什么是缓存穿透?缓存穿透是指查询一定不存在的数据。由于cachemiss和容错的考虑,如果从数据库中找不到数据,则不会写入cache。这样会导致每次请求的时候都在数据库中查询不存在的数据,也就失去了缓存的意义。这就是缓存穿透:请求的数据在缓存中遗漏了很多,导致请求去数据库。如果发生缓存穿透,还可能拉垮我们的数据库,导致整个服务瘫痪!2.2如何解决缓存穿透?解决缓存穿透的方案也有两种:由于请求的参数是非法的(每次请求的都是不存在的参数),我们可以使用布隆过滤器(BloomFilter)或者压缩过滤器进行提前拦截。这个请求去数据库层!当我们从数据库中找不到的时候,我们也把这个空对象设置到缓存中。下次请求时,可以从缓存中获取。这种情况下,我们一般会设置一个过期时间较短的空对象。缓存与数据库双写一致3.1对于读操作,流程如下。如果我们的数据在缓存中,那么直接取缓存。如果缓存中没有我们想要的数据,我们会先查询数据库,然后将数据库中查到的数据写入缓存。最后将数据返回给请求。3.2什么是缓存和数据库的双写一致性问题?如果只是查询的话,缓存数据和数据库数据都没有问题。但是当我们想要更新时呢?各种情况都可能导致数据库和缓存数据不一致。这里的不一致是指:数据库中的数据与缓存中的数据不一致。理论上只要我们设置key的过期时间,就可以保证缓存中的数据和数据库中的数据最终是一致的。因为只要缓存数据过期,就会被删除。后面读取的时候,因为没有缓存,可以去数据库中查数据,然后把数据库中查到的数据写入缓存中。除了设置过期时间,我们还需要采取更多措施,尽可能避免数据库和缓存不一致的情况。最后,本文带大家了解如何解决缓存雪崩、缓存穿透、保证缓存和数据库双写等问题。希望您阅读后会有所帮助。