redis面试题一

一、如何防止缓存击穿问题

在实际应用里面,我们会在程序和数据库之间增加一个缓存层,一方面是为了提升数据的检索效率,提升程序的性能,另一方面是为了缓解数据库的一个并发压力,缓存击穿表示请求因为某些原因全部打到了数据库,缓存并没有起到流量缓冲的一个作用

我认为有两种情况会导致缓存的一个击穿,第一种是在redis里保存的热点key在缓存过期的瞬间有大量的请求进来,那么导致了请求全部打到了数据库里面,第二种是客户端恶意发起大量不存在的key的一个请求,由于访问的key对应的数据本身也不存在,所以每一次必然都会穿透到数据库里面,导致缓存成为了一个摆设,总之,当redis承担了流量缓冲功能的时候,我们就需要考虑到redis失效导致并发压力过大,对于后端存储设备造成冲击的一个问题

我认为可以通过几种方法来解决:一对于热点数据,我们可以不设置过期时间,或者在访问数据的时候对数据过期时间进行续期;二对于访问量较高的缓存数据,我们可以设计多级缓存,尽量减少后端存储设备的压力;三使用分布式锁,当发现缓存失效时,不是先从数据库加载,而是先获取分布式锁,获得分布式锁的线程从数据库查询数据后写回到缓存里面,后续没有获得锁的线程只需要等待和重试就行了,这样的话就能够去避免大量请求压倒后端的一个存储设备的一个问题,这个方案虽然牺牲了一定的性能但是确保了数据库的一个稳定性;四对恶意攻击类的场景,可以使用布隆过滤器,应用启动的时候把存在的数据缓存到布隆过滤器里面。每一次请求进来的时候先访问布隆过滤器,如果不存在则说明这个数据一定没有在数据库里面,就没有必要再去访问数据库了

另外,我们在整个缓存的架构设计里面呢,除了尽可能的去避免缓存穿透的一个问题,还需要从全局的视角做整体的考虑,比如说业务隔离,多级缓存部署隔离和安全性考虑等。

二、谈谈对redis的理解

redis是一个基于key-value存储结构的Nosql开源内存数据库,它提供了5种常用的数据库类型,像String、Hash、ZSet、Set、List;那么针对于不同的结构呢,可以解决不同场景的问题,因此它可以去覆盖应用开发里面的大部分的业务场景,比如像top10的问题啊或者好友关注列表热点话题等等,其次由于redis本身是一个基于内存的一个存储并且在数据结构上做了大量的一些优化,所以IO的性能会比较好,在实际开发里面,我们会把它用在应用和数据库之间的一个分布式缓存中间件,并且呢它又是一个非关系数据库的存储,它不存在表之间的关联,查询的一些问题,所以它可以很好的去提升应用程序的数据IO效率,最后作为企业级开发来说,它又提供了主从复制+哨兵以及集群的方式去实现高可用,在redis里面呢通过hash槽的方式去实现了数据的分片,进一步提升了整体的一个性能和可扩展性

三、说说缓存雪崩和缓存穿透的理解以及如何避免

缓存雪崩就是存储在缓存里面的大量数据在同一个时刻全部过期,原本缓存组件能够扛住大部分流量全部请求到了数据库,从而导致数据库压力增加,造成数据库服务器的崩溃的一种现象,导致缓存雪崩的原因呢,我认为有几个方面:一缓存中间件宕机当然可以对缓存中间件做高可用集群来避免;二缓存中大部分key都设置了相同的过期时间导致同一时刻这些key都过期了,所以对于这个情况下可以在失效时间里面去增加1-5分钟的随机值,从而去避免同时失效的一个问题

缓存穿透的问题表示短时间内有大量的不存在的key请求到应用程序里面,而这些不存在的key呢在缓存里面又找不到,从而就导致全部的请求全部穿透到了数据库,造成数据库的压力增加,我认为这个场景的核心问题是针对于缓存的一种攻击行为,因为正常的业务里面即便是出现这样一个不存在key的情况,由于缓存的不断预热,影响也不会很大,而攻击行为就需要具备时间的一个持续性,而只有key确定在数据库里面不存在的情况下才能达到这样一个目的,所以我认为有两个方法可以去解决:把无效的key保存到redis里面并且设置一个特殊的值比如像"null"字符串,这样的话下次再来访问的时候,就不会去查数据库了,但是如果攻击者不断的用随机的不存在的key来访问也还是会存在相同的问题,所以可以使用布隆过滤器来实现,那么在系统启动的时候,我们可以把目标数据全部缓存到布隆过滤器里面,当攻击者去使用不存在的key来请求的时候,先到布隆过滤器里面去进行查询,如果不存在,就意味着这个key肯定在数据库里面也不存在,所以这个时候就不会去访问数据库,所以布隆过滤器还有个好处,就是它采用bitmap也就是位图来进行数据存储,所以它的占用内存空间是很小的,不过在我看来,你提出的这个问题真的有点过于放大它所带来的影响,当然也是要考虑,首先我认为为什么放大?是因为第一个在成熟的系统里面对于比较重要的热点数据必然会有一个专门的缓存系统来维护,同时它的过期时间的维护必然和其他的业务的key会有一定的区别,而且对于非常重要的场景,我们还会设计多级缓存的一个实现,其次即便是触发了缓存雪崩,那么数据库本身的容灾能力也并没有那么脆弱,数据库的主从、双主读写分离这些策略都可以去很好的缓解并发流量,最后数据库本身也有最大连接数的限制,超过限制的请求会被拒绝,再结合熔断机制也能够很好的去保护数据库系统,最多就是造成部分用户体验不好而已,另外在程序设计上,为了缓存未命中,导致大量请求穿透到数据库的问题,我们还可以在访问数据库这个环节里面去加锁,虽然影响了性能,但是对整个系统是安全的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值