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

分享几道Redis高频面试题,面试不愁

时间:2023-03-15 14:09:06 科技观察

1.Redis的应用场景有哪些?缓存:这应该是Redis的主要功能,也是大型网站必备的机制。合理使用缓存,不仅可以加快数据访问速度,还可以有效降低后端数据源的压力。SharedSession:对于一些依赖session功能的服务,如果需要从单机改为集群,可以选择redis统一管理session。消息队列系统:消息队列系统可以说是大型网站必不可少的基础组件,因为它具有业务解耦和非实时业务调峰的特点。Redis提供了发布订阅的功能和阻塞队列的功能。虽然和专业的消息队列相比不够强大,但是基本可以满足一般的消息队列功能。比如在分布式爬虫系统中,使用redis统一管理url队列。分布式锁:在分布式服务中。可以使用Redis的setnx函数来写分布式锁,虽然这个可能不是很常用。当然,也有排名、点赞等功能可以使用Redis来实现,但Redis也不是万能的。比如当数据量特别大的时候,就不适合Redis。我们知道Redis是基于内存的。虽然内存很便宜,但是如果你每天的数据量特别大,比如上亿的用户行为日志数据,用Redis来存储成本会很高。2、为什么单线程Redis这么快?Redis有多快?官方给出的答案是读写速度为每秒10万条。如果这是在单线程环境中实现的,您会感到惊讶吗?为什么?单线程Redis这么快?原因如下:纯内存操作:Redis完全基于内存,所以读写效率非常高。当然,Redis是有持久化操作的,而持久化操作都是fork子进程,并利用Linux系统的pagecache技术来完成的,并不会影响Redis的性能。单线程运行:单线程并不是坏事,单线程可以避免频繁的上下文切换,频繁的上下文切换也会影响性能。合理高效的数据结构采用非阻塞I/O多路复用机制:多I/O多路复用模型使用select、poll、epoll同时监听多个流的I/O事件。时间,当前线程会被阻塞,当一个或多个流有I/O事件时,会从阻塞状态唤醒,所以程序会轮询所有的流(epoll只轮询那些真正发送过事件的流),并且只顺序处理就绪流,这样就避免了很多无用的操作。3、谈谈Redis的数据结构和使用场景Redis提供了5种数据结构,每种数据结构都有不同的使用场景。1.String字符串类型是Redis最基本的数据结构。首先,key都是string类型,其他几种数据结构都是建立在string类型的基础上的。我们经常使用的设置键值的命令是string。常用于缓存、计数、共享Session、限速等。2.HashHash在Redis中,hash类型指的是键值本身是键值对结构,如value={{field1,value1},...{fieldN,valueN}},添加命令:hsetkeyfieldvalue。Hash可以用来存储用户信息,比如实现购物车3、List列表(列表)类型用来存储多个有序的字符串。可以做一个简单的消息队列功能。另外可以使用lrange命令实现基于Redis的分页功能,性能优异,用户体验好。4.Setset(集合)类型也用于存储多个字符串元素,但与list类型不同的是,set中不允许有重复的元素,set中的元素是无序的,不能索引下标获取元素.使用Set的交集、并集和差集运算,您可以计算出共同偏好、所有偏好和您自己的独特偏好。5.SortedSetSortedSet多了一个权重参数Score,集合中的元素可以按照Score进行排列。可以作为排行榜应用,取TOPN操作4、说说Redis的数据过期和淘汰策略先给大家一个结论,Redis中的数据过期策略采用的是定时删除+惰性删除的策略。1、定期删除和惰性删除策略有哪些?周期删除策略:Redis启动一个定时器,定时监控所有key,判断key是否过期,如果过期则删除。这种策略可以保证过期的key最终会被删除,但是它也有严重的缺点:每次都要遍历内存中的所有数据,消耗大量的CPU资源,并且当key已经过期,但是定时器还处于未觉醒状态,这段时间钥匙还是可以使用的。懒删除策略:在获取key时,先判断key是否过期,过期则删除。这种方法有一个缺点:如果key没有被使用过,它会一直在内存中,但实际上已经过期了,会浪费很多空间。2、定时删除+惰性删除策略是如何实现的?这两种策略自然是互补的。合并之后,定时删除的策略发生了一些变化。不是每次都扫描所有key,而是随机选择一部分key进行校验,减少了CPU资源的消耗。惰性删除策略补充了未检查的键,基本满足所有要求。但有时正是这样的巧合,数据既没有被定时器提取也没有被使用。这些数据怎么会从内存中消失呢?没关系,还有内存淘汰机制。当内存不够用时,内存淘汰机制就会发挥作用。Redis内存淘汰机制有以下策略:noeviction:当内存不足以容纳新写入的数据时,新的写入操作会报错。(Redis默认策略)allkeys-lru:当内存不足以容纳新写入的数据时,在key空间中,移除最近最少使用的Key。(推荐)allkeys-random:当内存不足以容纳新写入的数据时,在key空间中,随机移除一个Key。volatile-lru:当内存不足以容纳新写入的数据时,移除key空间中设置过期时间的最近最少使用的Key。在这种情况下,Redis一般既作为缓存,又作为持久化存储。volatile-random:当内存不足以容纳新写入的数据时,从设置过期时间的key空间中随机取出一个Key。volatile-ttl:当内存不足以容纳新写入的数据时,在设置了过期时间的key空间中,先删除过期时间较早的Key。修改内存淘汰机制,只需要在redis.conf配置文件中配置maxmemory-policy参数即可。5、如何解决Redis缓存穿透和缓存雪崩问题缓存雪崩:由于缓存层承载了大量的请求,存储层得到了有效的保护,但是如果缓存层由于某些原因无法提供服务,比如Redis节点挂了,热点的所有key都失效了。在这些情况下,所有请求都会直接向数据库请求,这可能会导致数据库宕机。预防和解决缓存雪崩问题,可以从以下三个方面入手:1、使用Redis高可用架构:使用Redis集群,保证Redis服务不会挂掉2、缓存时间不一致:添加一个随机取值,避免集体失败3.限流降级策略:有一定的记录,比如个性化推荐服务不可用,换成热点数据推荐服务缓存穿透:缓存穿透是指查询一个数据那根本不存在,所以的数据肯定不在缓存中,这样就会导致所有的请求都落在数据库上,数据库可能就宕机了。防止和解决缓存穿透问题,可以考虑以下两种方法:1、缓存空对象:缓存空值,但是这种方式有个问题,大量无效的空值会占用空间,这是非常浪费的。2.布隆过滤器拦截:首先将所有可能的查询键映射到布隆过滤器。查询的时候先判断这个key是否存在于Bloomfilter中,然后继续往下执行。如果不存在,则直接返回。布隆过滤器有一定的误判,所以你的业务需要允许一定的容错。