首页 > 数据库 >Redis常见面试题

Redis常见面试题

时间:2024-09-27 11:21:42浏览次数:8  
标签:面试题 缓存 删除 过期 常见 Redis 内存 key

过期删除策略

删除达到过期时间的key。
  • 1)定时删除

对于每一个设置了过期时间的key都会创建一个定时器,一旦到达过期时间就立即删除。该策略可以立即清除过期的数据,对内存较友好,但是缺点是占用了大量的CPU资源去处理过期的数据,会影响Redis的吞吐量和响应时间。

  • 2)惰性删除

当访问一个key时,才判断该key是否过期,过期则删除。该策略能最大限度地节省CPU资源,但是对内存却十分不友好。有一种极端的情况是可能出现大量的过期key没有被再次访问,因此不会被清除,导致占用了大量的内存。

在计算机科学中,懒惰删除(英文:lazy deletion)指的是从一个散列表(也称哈希表)中删除元素的一种方法。在这个方法中,删除仅仅是指标记一个元素被删除,而不是整个清除它。被删除的位点在插入时被当作空元素,在搜索之时被当作已占据。

  • 3)定期删除

每隔一段时间,扫描Redis中过期key字典,并清除部分过期的key。该策略是前两者的一个折中方案,还可以通过调整定时扫描的时间间隔和每次扫描的限定耗时,在不同情况下使得CPU和内存资源达到最优的平衡效果。

在Redis中,同时使用了定期删除和惰性删除。不过Redis定期删除采用的是随机抽取的方式删除部分Key,因此不能保证过期key 100%的删除。

Redis结合了定期删除和惰性删除,基本上能很好的处理过期数据的清理,但是实际上还是有点问题的,如果过期key较多,定期删除漏掉了一部分,而且也没有及时去查,即没有走惰性删除,那么就会有大量的过期key堆积在内存中,导致redis内存耗尽,当内存耗尽之后,有新的key到来会发生什么事呢?是直接抛弃还是其他措施呢?有什么办法可以接受更多的key?

内存淘汰策略

Redis的内存淘汰策略,是指内存达到maxmemory极限时,使用某种算法来决定清理掉哪些数据,以保证新数据的存入。

Redis的内存淘汰机制包括:

  • noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错。
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间(server.db[i].dict)中,移除最近最少使用的 key(这个是最常用的)。
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间(server.db[i].dict)中,随机移除某个 key。
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间(server.db[i].expires)中,移除最近最少使用的 key。
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间(server.db[i].expires)中,随机移除某个 key。
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间(server.db[i].expires)中,有更早过期时间的 key 优先移除。

在配置文件中,通过maxmemory-policy可以配置要使用哪一个淘汰机制。

什么时候会进行淘汰?

Redis会在每一次处理命令的时候(processCommand函数调用freeMemoryIfNeeded)判断当前redis是否达到了内存的最大限制,如果达到限制,则使用对应的算法去处理需要删除的key。

在淘汰key时,Redis默认最常用的是LRU算法(Latest Recently Used)。Redis通过在每一个redisObject保存lru属性来保存key最近的访问时间,在实现LRU算法时直接读取key的lru属性。

具体实现时,Redis遍历每一个db,从每一个db中随机抽取一批样本key,默认是3个key,再从这3个key中,删除最近最少使用的key。

Redis的缓存击穿、缓存雪崩、缓存穿透

1)缓存穿透

参考资料:
  • 什么是缓存穿透
    • 正常情况下,我们去查询数据都是存在。那么请求去查询一条压根儿数据库中根本就不存在的数据,也就是缓存和数据库都查询不到这条数据,但是请求每次都会打到数据库上面去。这种查询不存在数据的现象我们称为缓存穿透
  • 穿透带来的问题
    • 试想一下,如果有黑客会对你的系统进行攻击,拿一个不存在的id 去查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉。
  • 解决办法
    • 缓存空值:之所以会发生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查询都到数据库去了。那么我们就可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候,直接返回null 。这样,就不用在到数据库中去走一圈了,但是别忘了设置过期时间。
    • BloomFilter(布隆过滤):将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。在缓存之前在加一层 BloomFilter ,在查询的时候先去 BloomFilter 去查询 key 是否存在,如果不存在就直接返回,存在再走查缓存 -> 查 DB。

话术:

缓存穿透有两种解决方案:其一是把不存在的key设置null值到缓存中。其二是使用布隆过滤器,在查询缓存前先通过布隆过滤器判断key是否存在,存在再去查询缓存。

设置null值可能被恶意针对,攻击者使用大量不存在的不重复key ,那么方案一就会缓存大量不存在key数据。此时我们还可以对Key规定格式模板,然后对不存在的key做正则规范匹配,如果完全不符合就不用存null值到redis,而是直接返回错误。

2)缓存击穿

**相关资料**:
  • 什么是缓存击穿?

key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题。

当这个key在失效的瞬间,redis查询失败,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

  • 解决方案:
    • 使用互斥锁(mutex key):mutex,就是互斥。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用Redis的SETNX去set一个互斥key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现互斥的效果。
    • 软过期:也就是逻辑过期,不使用redis提供的过期时间,而是业务层在数据中存储过期时间信息。查询时由业务程序判断是否过期,如果数据即将过期时,将缓存的时效延长,程序可以派遣一个线程去数据库中获取最新的数据,其他线程这时看到延长了的过期时间,就会继续使用旧数据,等派遣的线程获取最新数据后再更新缓存。

推荐使用互斥锁,因为软过期会有业务逻辑侵入和额外的判断。

面试话术

缓存击穿主要担心的是某个Key过期,更新缓存时引起对数据库的突发高并发访问。因此我们可以在更新缓存时采用互斥锁控制,只允许一个线程去更新缓存,其它线程等待并重新读取缓存。例如Redis的setnx命令就能实现互斥效果。

3)缓存雪崩

**相关资料**:

缓存雪崩,是指在某一个时间段,缓存集中过期失效。对这批数据的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。

解决方案:

  • 数据分类分批处理:采取不同分类数据,缓存不同周期
  • 相同分类数据:采用固定时长加随机数方式设置缓存
  • 热点数据缓存时间长一些,冷门数据缓存时间短一些
  • 避免redis节点宕机引起雪崩,搭建主从集群,保证高可用

面试话术:

解决缓存雪崩问题的关键是让缓存Key的过期时间分散。因此我们可以把数据按照业务分类,然后设置不同过期时间。相同业务类型的key,设置固定时长加随机数。尽可能保证每个Key的过期时间都不相同。

另外,Redis宕机也可能导致缓存雪崩,因此我们还要搭建Redis主从集群及哨兵监控,保证Redis的高可用。

标签:面试题,缓存,删除,过期,常见,Redis,内存,key
From: https://blog.csdn.net/m0_68424500/article/details/142584178

相关文章

  • 常见css属性方法
    上下拉动滚动条时卡顿、慢body{-webkit-overflow-scrolling:touch;overflow-scrolling:touch;}禁止复制、选中文本Element{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;user-select:none;}判断是否......
  • HTML+CSS 常见效果
    静态图片动画html<divclass="loader">Loading…</div>css@keyframesloader{to{background-position:-800px0;}}.loader{width:100px;height:100p......
  • 【春秋招必看】Unity相关笔试面试题(内有完整答案)第五期
    欢迎来到光光的奇妙冒险,我是你们的煎饼光子老师。今天是我们的第五期笔试面试题总结。C#部分:1、以上代码,谁的效率更高?为什么?答案:代码2的效率更高因为List的本质是数组,在初始化时,如果不默认为其指明分配多少容量,它会不断扩容扩容会带来效率的降低和垃圾的产生效率的降......
  • PbootCMS全站模板date时间标签/时间格式常见的8种调用方式
    全站模板中日期时间标签和时间格式的常见调用方式,绘制成表格形式:调用方式适用页面格式效果[list:date]首页/列表页2021-12-0609:12:30[list:datestyle=Y-m-d]首页/列表页2021-12-06[list:datestyle=Y]首页/列表页2021[list:datestyle=m-d]首页/列表页......
  • redis有序集合多字段排序
    首先,redis有序集合本身是不支持多字段排序的例如ZADDusers25AliceZADDusers25BobZADDusers10Carol只能通过前面的分数这一个维度来实现,如果现在引入了另一个字段,可以在分数值(利用阿拉伯数字)上做手脚例如,时间维度2023-01-012023-01-022023-01-03这......
  • 前端面试题(十)
    51.前端性能优化在前端开发中,性能优化是面试中的一个常见话题。面试官通常会希望候选人具备识别性能瓶颈并提出相应解决方案的能力。以下是一些常见的前端性能优化面试题及其答案。1.前端性能优化有哪些常见手段?前端性能优化的手段可以从多个维度考虑,主要包括:减少HT......
  • PbootCms内页打不开的常见情况汇总
    在使用PBootCMS建站时,如果遇到内页无法正常访问的问题,通常与伪静态配置有关。以下是一些常见问题及解决方法,包括关闭伪静态和重新配置伪静态的方法。常见问题点击任何链接都跳转到首页内页访问报错解决方案方案一:关闭伪静态进入后台管理界面登录PBootCMS后台管理系统......
  • Robot Framework 自动化测试部署常见问题及处理方法(三)
    书接上文8.关于IE浏览器IE浏览器必须是原生版,即Windows系统原版,非手动升级后的版本9.用例执行过程中,遇到元素定位不到的情况原因:⑴xpath动态变化⑵有frame/iframe⑶没有设置等待,元素未加载完成解决方法:⑴若xpath动态变化:重写xpath⑵若有frame/iframe:参照第二节第10点【......
  • 易优cms安全设置常见问题_Eyoucms安全设置问题解决方法
    易优EyouCMS的安全设置对于保护网站免受攻击非常重要。下面列出了一些关于易优CMS安全设置的常见问题及其解决方法:1.目录权限设置为了防止未经授权的访问,应该合理设置网站目录的权限。例如,上传目录通常需要写入权限,而其他目录则应限制权限以防止恶意文件上传或执行。解决方法......
  • 使用 Redis 记录用户连续登录天数的方法及代码分享
    目录标题:使用Redis记录用户连续登录天数的方法及代码分享一、为什么不适合放在数据库中二、Redis的bitmap介绍三、存储方式及统计方法(一)以每天维度存储(二)以用户维度存储在本文中,我们将探讨如何使用Redis记录用户连续登录天数的问题。这是一个在面试中可能会遇到......