Redis实战(十一)Redis面试题

序言

单线程的redis为什么这么快?

1.纯内存操作不需要进行磁盘的 IO

2.单线程操作避免了频繁上下文切换

3.采用非阻塞的多路I/O复用模型

什么是路I/O复用模型?

核心是监听socket,压到队列。文件事件分派器快速处理。

假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?

  redis是单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了。

三种过期策略

定时删除

惰性删除

定期删除

Redis的内存回收机制

Redis的内存回收主要分为过期删除策略存淘汰策略两部分。

你能说说我们一般如何应对缓存雪崩以及穿透问题吗?

1.缓存穿透:查询一个必然不存在的数据。比如文章表,查询一个不存在的id,每次都会访问DB,如果有人恶意破坏,很可能直接对DB造成影响。

解决办法:只要从数据库没有查到值,就写一个空值到缓存。

2.缓存失效:如果缓存集中在一段时间内失效,DB的压力凸显。这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

解决办法:限流降级。

高并发场景下的缓存+数据库双写不一致问题分析与解决方案设计

解决方案:读写请求串行到一个内存队列中。

分布式锁是啥?对比下redis和zk两种分布式锁的优劣?

利用redis的setnx(key, value):“set if not exits”,若该key-value不存在,则成功加入缓存并且返回1,否则返回0。在有效时间内如果设置成功则获取执行限权,没有那就获取权限失败。

先操作缓存,还是数据库?

读请求:

先读缓存,如果没有命中,读数据库,再set回缓存

写请求:

先缓存,再数据库

缓存,使用delete,而不是set

使用set的情况:第一步成功,第二步失败,会导致,缓存里是set后的数据,数据库里是之前的数据,数据不一致,业务无法接受。

使用delete的情况:第一步成功,第二步失败,会导致,缓存里没有数据,数据库里是之前的数据,数据没有不一致,对业务无影响。只是下一次读取,会多一次cache miss。

什么是跳跃表?

  首先先明白数组、链表带来的插入数据的复杂比如:

当数组里存有 1,2,3,4,6,7,8,9,10,11 时,我们向数组内插入5,使用二分查找法快速查找到与3最相近的数字(O(logN)),然后再将其他数字右移(O(N)),那么数组的插入算法的时间复杂度就是O(N)当链表里存有 1,2,3,4,6,7,8,9,10,11时,往链表中插入5,那么就需要逐一比较,时间复杂度为O(N)这样简单的数字看起来插入查询似乎并没有什么性能的影响,但是思考一下,如果此时数据库存在10万条数据,对这个数据进行查询或者插入,是非常耗费性能的。

  所以这个时候提出来跳跃表:

资料

常见的Redis面试"刁难"问题,值得一读

面试前必须要知道的Redis面试题

竟先操作缓存,还是数据库?

原文地址:https://www.cnblogs.com/cnki/p/10824492.html