01

谈谈你对Redis的理解

关于Redis是什么,想必大部分人都能脱口而出——它是一个分布式缓存中间件。可这样回答有问题吗?当然有。

准确来说,Redis是一个基于内存实现的key-value数据结构的NoSQL数据库。注意,这里有3个关键词,分别是内存存储、key-value结构和NoSQL。

内存存储,是指所有数据是存储在内存里面,数据的I/O性能比较高。当然,Redis也提供了持久化策略来避免内存数据丢失的问题。key-value 表示数据的存储方式,除了Redis,还有LevelDB、Scalaris等。而NoSQL指的是一种非关系型数据库,相比于传统的关系型数据库而言,更多地考虑到扩展性、性能、大数据量的存储等,弥补了关系型数据库的短板。列式存储ClickHouse、Cassandra、文档存储MongoDB、图形存储Neo4J等都属于NoSQL范畴。

Redis就是这么一个基于key-value存储结构的NoSQL开源内存数据库。它提供了5种常用的数据类型:String、Map、Set、ZSet、List。针对不同的结构,可以解决不同场景中的问题。因此它可以覆盖应用开发中大部分的业务场景,比如top10问题、好友关注列表、热点话题等。

由于 Redis 是基于内存存储的,并且在数据结构上做了大量的优化,所以 I/O 性能比较高,在实际开发中,会把它作为应用与数据库之间的一个分布式缓存组件。并且它又是一个非关系型数据的存储,不存在表之间的关联查询问题,所以它可以很好地提升应用程序的数据I/O效率。

作为企业级开发工程师来说,Redis又提供了主从复制+哨兵,以及集群方式实现高可用。在Redis集群里面,通过Hash槽的方式实现了数据分片,进一步提升了性能。

面试点评:

对某种技术的理解这一类问题比较宽泛。在面试过程中,考查这类问题有两个很重要的目的:

1)面试官希望求职者能多说一些东西,从而更好地对求职者的整体情况和能力有一个清晰的判断,因此通过这类问题,可以找到一些了解求职者的突破口。

2)对这类问题其实没有标准答案,更多的是基于求职者对它的理解的一个总结,这反而能够更好地考查求职者的技术积累和逻辑表达能力。

所以,求职者在回答过程中,需要尽可能逻辑清晰、简单明了地表述出来,否则很难得到认可。

02

如何解决缓存雪崩、缓存穿透和缓存击穿问题

缓存雪崩是指存储在缓存里面的大量数据,在同一个时刻全部过期,原本缓存组件扛住的大部分流量全部到达了数据库,导致数据库压力增加,造成数据库服务器崩溃的现象,如下图所示。

解析Redis缓存雪崩穿透问题及其解决方案_redis

导致缓存雪崩的主要原因有两个:

  • 缓存中间件宕机,可以通过对缓存中间件做高可用集群来避免。
  • 缓存中大部分key都设置了相同的过期时间,导致同一时刻这些key都过期了。对于这样的情况,可以在失效时间上增加一个1~5 min的随机值。

缓存穿透问题,表示短时间内有大量不存在的key请求到应用里面,而这些不存在的key在缓存里面又找不到,从而全部穿透到了数据库,造成数据库压力。这个场景的核心问题是针对缓存的一种攻击行为,因为在正常的业务里面,即便出现了这样的情况,由于缓存的不断预热,影响不会很大。而攻击行为就需要具备时间上的持续性,而只有key确实也不存在于数据库中的情况下,才能达到这个目的。有两个方法可以解决这个问题:

把无效的key也保存到Redis里面,并且设置一个特殊的值,比如“null”,下次再访问,就不会去查数据库了。

如果攻击者不断用随机的不存在的key访问数据库,那么还是会存在问题,所以可以用布隆过滤器来实现,在系统启动的时候把目标数据全部缓存到布隆过滤器里面,当攻击者用不存在的key来请求的时候,先到布隆过滤器里面查询,如果不存在,那么意味着这个key在数据库里面也不存在,如下图所示。布隆过滤器还有一个好处,就是它采用了bitmap存储数据,占用的内存空间很少。

解析Redis缓存雪崩穿透问题及其解决方案_Redis_02

不过,这个问题有点过于放大了它带来的影响。

首先,在一个成熟的系统里面,对于比较重要的热点数据,必然会有一个专门的缓存系统来维护,同时它的过期时间的维护必然和其他业务的key有一定的差别,而且对于非常重要的场景,我们还会设计多级缓存系统。

其次,即便触发了缓存雪崩,数据库本身的容灾能力也没有那么脆弱,数据库的主从、双主、读写分离这些策略都能够很好地缓解并发流量。

最后,数据库本身也有最大连接数的限制,超过限制的请求会被拒绝,再结合熔断机制,也能够很好地保护数据库系统,最多就是造成部分用户体验不好。另外,在程序设计上,为了避免缓存未命中导致大量请求穿透到数据库的问题,还可以在访问数据库这个环节加锁。虽然影响了性能,但对系统是安全的,如下图所示。

解析Redis缓存雪崩穿透问题及其解决方案_缓存_03

总而言之,解决的办法很多,具体选择哪种方式,还是要看具体的业务场景。

面试点评:

这个问题在大厂中多见,在中小企业很难遇到这种缓存雪崩、缓存穿透问题。网上对这个问题的回答五花八门,但是不管怎么回答,找到根本问题,然后提供一些关键点,基本上就没问题。


亲爱的程序员求职者们,相信你们一定深有体会,求职面试这条路有多难走。

现在有了一本强大的新书空降,在这炽热的夏日带来一股清凉的Java知识。这本名叫《Java面试八股文:高频面试题与求职攻略一本通》,简直是Java求职者的救星。

书中囊括了Java面试的方方面面近200道高频面试题,从Java基础知识、并发编程、集合原理,到JVM原理、I/O与网络编程,再到设计模式、分布式与微服务,MySQL数据库、缓存与NoSQL,消息中间件……应有尽有,想不掌握都难!而且书中还提供了大量实战场景与面试简历实操技巧。近20个经典高频实战场景解决方案,从服务器反应慢到秒杀设计,从架构设计到常见解决方案,无一不是伤害求职者心脏的“锋芒之剑”。同时,更有10多个面试简历实操技巧,包括简历编写与投递技巧、面试谈薪技巧、求职决策技巧等,一次性解决你的求职难题!

解析Redis缓存雪崩穿透问题及其解决方案_Redis_04

相信这本书可以成为你职业生涯中的有力助推器,事半功倍、轻松捞到心仪的Java工作。别犹豫了,已经给各位粉丝老爷申请到了最优惠的价格,冲冲冲,最后祝愿大家都能拿到自己心仪的Offer!