Redis 常见经典面试题

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis 常见经典面试题

槽位为什么设计为16384个

Redis集群模式下,会有多个节点,节点之间需要进行pingpong心跳通信,通信内容除了消息类型,节点id外,还会在消息主题中携带总结点数十分之一的节点信息进行交换,相互告知。如果槽位分配过大,会导致心跳通信的心跳包过大,浪费带宽且没必要,甚至容易造成网络拥堵。如果哈希槽设计过少,例如几千个的话,我们知道redis建议集群模式不要超过1000节点,那么如果是满载1000个节点,平分几千个哈希槽,在节点迁移时候容易出现数据倾斜,造成单节点访问过高,甚至造成节点连续崩溃,最终导致大规模服务集群雪崩相像。

Redis为什么快

  • Redis完全基于内存
  • Redis整个结构类似于HashMap,查找和操作复杂度为O(1),不需要和MySQL查找数据一样需要产生随机磁盘IO或者全表
  • Redis对于客户端的处理是单线程的,采用单线程处理所有客户端请求,避免了多线程的上下文切换和线程竞争造成的开销
  • 底层采用select/epoll多路复用的高效非阻塞IO模型
  • 客户端通信协议采用RESP,简单易读,避免了复杂请求的解析开销

缓存雪崩(同一时间大量热点key过期)

缓存雪崩造成的原因是因为我们在做缓存时为了保证内存利用率,一般在写入数据时都会给定一个过期时间,而就是因为过期时间的设置有可能导致大量的热点key在同一时间内全部失效,此时来了大量请求访问这些key,而redis中却没有这些数据,从而导致所有请求直接落入DB查询,造成DB出现瓶颈或者直接被打宕导致雪崩情况的发生。

关于解决方案的的话也可以从多个维度来考虑:

  • 设置热点数据永不过期,避免热点数据的失效导致大量的相同请求落入DB
  • 错开过期时间的设置,根据业务以及线上情况合理的设置失效时间
  • 使用分布式锁或者MQ队列使得请求串行化,从而避免同一时间请求大量落入DB(性能会受到很大的影响)

缓存穿透

请求参数不合理,导致Redis一直去数据库中查询。

缓存穿透这个问题是由于请求参数不合理导致的,比如对外暴露了一个接口getUser?userID=xxx,而数据库中的userID是从1开始的,当有黑客通过这个接口携带不存在的ID请求时,比如:getUser?userID=-1,请求会先来到Redis中查询缓存,但是发现没有对应的数据从而转向DB查询,但是DB中也无此值, 所以也无法写入数据到缓存,而黑客就通过这一点利用“肉鸡”等手段疯狂请求这个接口,导致出现大量redis不存在数据的请求落入DB,从而导致DB出现瓶颈或者直接被打宕机,整个系统陷入瘫痪。

解决方案:

  • 做IP限流与黑名单,避免同一IP瞬间发送大量请求
  • 对于请求做非法校验,对于携带非法参数的请求直接过滤
  • 对于DB中查询不存在的数据写入Redis中“Not Data”并设置短暂的过期时间,下次请求能够直接被拦截在redis而不会落入DB
  • 布隆过滤器

缓存击穿

一个热点key突然过期,数据库无法承受大量请求。

缓存击穿和缓存雪崩有点类似,都是由于请求的key过期导致的问题,但是不同点在于失效key的数量,对于雪崩而言指的是大量的key失效导致大量请求落入DB,而对于击穿而言,指的是某一个热点key突然过期,而这个时候又突然又大量的请求来查询它,但是在redis中却并没有查询到结果从而导致所有请求全部打向DB,导致在这个时刻DB直接被打穿。

解决方案的话也是有多种:

  • 设置热点key永不过期
  • 做好redis监控,请求串行化访问(性能较差)
  • 使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

redis淘汰策略

redis在5.0之前为我们提供了六种淘汰策略,而5.0为我们提供了八种,但是大体上来说这些lru、lfu、random、ttl四种类型

  • 在Redis中,数据有一部分访问频率较高,其余部分访问频率较低,或者无法预测数据的使用频率时,设置allkeys-lru是比较合适的。
  • 如果所有数据访问概率大致相等时,可以选择allkeys-random。
  • 如果研发者需要通过设置不同的ttl来判断数据过期的先后顺序,此时可以选择volatile-ttl策略。
  • 如果希望一些数据能长期被保存,而一些数据可以被淘汰掉时,选择volatile-lru或volatile-random都是比较不错的。
  • 由于设置expire会消耗额外的内存,如果计划避免Redis内存在此项上的浪费,可以选用allkeys-lru策略,这样就可以不再设置过期时间,高效利用内存了。
  • maxmemory-policy:参数配置淘汰策略。maxmemory:限制内存大小。

三种键删除策略

redis删除Key的策略策略有三种:

  • 定时删除:在设置键的过期时间的同时,设置一个定时器,当键过期了,定时器马上把该键删除。(定时删除对内存来说是友好的,因为它可以及时清理过期键;但对CPU是不友好的,如果过期键太多,删除操作会消耗过多的资源。)
  • 惰性删除:key过期后任然留在内存中不做处理,当有请求操作这个key的时候,会检查这个key是否过期,如果过期则删除,否则返回key对应的数据信息。(惰性删除对CPU是友好的,因为只有在读取的时候检测到过期了才会将其删除。但对内存是不友好,如果过期键后续不被访问,那么这些过期键将积累在缓存中,对内存消耗是比较大的。)
  • 定期删除:redis数据库默认每隔100ms就会进行随机抽取一些设置过期时间的key进行检测,过期则删除。(定期删除是定时删除和惰性删除的一个折中方案。可以根据实际场景自定义这个间隔时间,在CPU资源和内存资源上作出权衡。)

Redis三种持久化机制

Redis的确是将数据存储在内存的,但是也会有相关的持久化机制将内存持久化备份到磁盘,以便于重启时数据能够重新恢复到内存中,避免数据丢失的风险。而Redis持久化机制由三种,在4.X版本之前Redis只支持AOF以及RDB两种形式持久化,但是因为AOF与RDB都存在各自的缺陷,而在4.x版本之后redis还提供一种新的持久化机制:混合型持久化(但是最终生成的文件还是AOF)。

RDB 持久化

RDB 持久化把内存中当前进程的数据生成快照(.rdb)文件保存到硬盘的过程,有手动触发和自动触发:

  • save:阻塞当前 Redis,直到 RDB 持久化过程完成为止,若内存实例比较大 会造成长时间阻塞,线上环境不建议用它
  • bgsave:redis 进程执行 fork 操作创建子进程,由子进程完成持久化,阻塞时间很短(微秒级),是 save 的优化
  • bgsave过程:通过fork创建子进程,RDB 持久化过程由子进程负责,会在后台异步进行快照操作,快照同时还可以响应客户端请求

    而且RDB 是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,重启时加载这个文件达到数据恢复。

  • redis RDB持久化默认开启 save 900 1 -- 900s内存在1个写操作 save 300 10 -- 300s内存在10个写操作 save 60 10000 -- 60s内存在10000个写操作 如上是RDB的自动触发的默认配置,当操作满足如上条件时会被触发。
  • RDB优缺点:

    • 优点:使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能;而且RDB文件存储的是压缩的二进制文件,适用于备份、全量复制,可用于灾难备份,同时RDB文件的加载速度远超于AOF文件。
    • 缺点:RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候,因为RDB无法做到实时持久化,而且每次都要创建子进程,频繁创建成本过高;备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(需要的内存是原本的两倍);还有一点,RDB文件保存的二进制文件存在新老版本不兼容的问题。

AOF持久化

而AOF持久化方式能很好的解决RDB持久化方式造成的数据丢失,AOF持久化到硬盘中的并不是内存中的数据快照,而是和MySQL的belog日志一样记录写入命令,AOF的持久化策略也有三种:

  • appendfsync always:同步持久化形式,每次发生数据更改都将命令追加到AOF文件,因为每次写入时都记录会产生大量磁盘IO,从而性能会受到影响,但是数据最安全。
  • appendfsync everysec:redis开启AOF后的缺省配置,异步操作,每秒将写入命令追加到AOF文件,如果在刚持久化之后的一秒内宕机,会造成1S的数据丢失。
  • appendfsync no:redis并不直接调用文件同步,而是交给操作系统来处理,操作系统可以根据buffer填充情况/通道空闲时间等择机触发同步;这是一种普通的文件操作方式。性能较好,在物理服务器故障时,数据丢失量会因 OS 配置有关。

AOF持久化机制优缺点:

  • 优点:根据不同的fsync策略可以保证数据丢失风险降到最低,数据能够保证是最新的,fsync是后台线程在处理,所以对于处理客户端请求的线程并不影响。
  • 缺点:文件体积由于保存的是所有命令会比RDB大上很多,而且数据恢复时也需要重新执行指令,在重启时恢复数据的时间往往会慢很多。虽然fsync并不是共用处理客户端请求线程的资源来处理的,但是这两个线程还是在共享同一台机器的资源,所以在高并发场景下也会一定受到影响。

AOF rewrite操作

随着redis在线上运行的时间越来越久,客户端执行的命令越来越多,AOF的文件也会越来越大,当AOF达到一定程度大小之后再通过AOF文件恢复数据是异常缓慢的,那么对于这种情况redis在开启AOF持久化机制的时候会存在AOF文件的重写,缺省配置是当AOF文件比上一次重写时的文件大小增长100%并且文件大小不小于64MB时会对整个AOF文件进行重写从而达到“减肥”的目的。

而AOF rewrite 操作就是“压缩”AOF 文件的过程,当然 redis 并没有采用“基于原 aof 文件”来重写的方式,而是采取了类似 snapshot 的方式:基于 copy-on-write,全量遍历内存中数据,然后逐个序列到aof 文件中。因此 AOF rewrite 能够正确反应当前内存数据的状态,这正是我们所需要的;rewrite 过程中,对于新的变更操作将仍然被写入到原 AOF 文件中,同时这些新的变更操作也会被 redis 收集起来。当内存数据被全部写入到新的 aof 文件之后,收集的新的变更操作也将会一并追加到新的 aof 文件中,此后将会重命名新的 aof 文件为 appendonly.aof, 此后所有的操作都将被写入新的 aof 文件。如果在rewrite 过程中,出现故障,将不会影响原 AOF 文件的正常工作,只有当 rewrite 完成之后才会切换文件,因为 rewrite 过程是比较可靠的,触发 rewrite 的时机可以通过配置文件来声明,同时 redis 中可以通过 bgrewriteaof 指令人工干预。

项目中redis采用的是那种持久化方式

在项目中如果redis中不仅仅只是用来做缓存,其中还存储着一些MySQL中不存在的数据,所以数据的安全性要求比较高,而RDB因为并不是实时的持久化,会出现数据丢失,但是采用AOF形式在重启、灾备、迁移的时候过程异常耗时,也并不理想,所以在我们线上是同时采用两种形式的。

线上双开加载顺序:

RDB和AOF同时开启时,会优先加载AOF文件,因为AOF文件的数据完整性是最高的,如果没有AOF文件,则加载RDB,存在RDB文件,则加载RDB文件,加载成功则启动成功。

4.x之后的混合型持久化

在redis4.x之后推出了混合型持久化机制,因为RDB虽然加载快但是存在数据丢失,AOF数据安全但是加载缓慢,redis为了解决这个问题,带来了一个新的持久化选项——混合持久化。

将RDB文件的内容和增量的AOF日志文件存在一起。这里的AOF日志不再是全量 的日志,而是自持久化开始到持久化结束的这段时间发生的增量AOF日志,通常这部分AOF日志很小。redis重启的时候,可以先加载RDB的内容,然后再重放增量AOF日志,就可以完全替代之前的AOF全量文件重放,恢复效率因此大幅得到提升(混合型持久化最终生成的文件后缀是.aof,可以通过redis.conf文件中 aof-use-rdb-preamble yes 配置开启)。

混合型持久化优点:

结合了RDB和AOF的优点,使得数据恢复的效率大幅提升

混合型持久化缺点:

兼容性不好,redis-4.x新增,虽然最终的文件也是.aof格式的文件,但在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Redis Sentinel
【怒怼大厂面试官】听说你精通Redis?说说Redis哨兵
面试官:Redis哨兵知道吧?知道的,Sentinel哨兵本质是一个运行在特殊模式下的Redis服务器。面试官:嗯然后呢?它的主要作用是通过检测Redis主从服务器的下线状态,选举出新Redis主服务器,也就是故障转移,来保证Redis的高可用性。
78 4
【怒怼大厂面试官】听说你精通Redis?说说Redis哨兵
|
5天前
|
NoSQL MongoDB Redis
Python与NoSQL数据库(MongoDB、Redis等)面试问答
【4月更文挑战第16天】本文探讨了Python与NoSQL数据库(如MongoDB、Redis)在面试中的常见问题,包括连接与操作数据库、错误处理、高级特性和缓存策略。重点介绍了使用`pymongo`和`redis`库进行CRUD操作、异常捕获以及数据一致性管理。通过理解这些问题、易错点及避免策略,并结合代码示例,开发者能在面试中展现其技术实力和实践经验。
91 8
Python与NoSQL数据库(MongoDB、Redis等)面试问答
|
16天前
|
缓存 NoSQL Java
面试官:Redis如何实现延迟任务?
延迟任务是计划任务,用于在未来特定时间执行。常见应用场景包括定时通知、异步处理、缓存管理、计划任务、订单处理、重试机制、提醒和数据采集。Redis虽无内置延迟任务功能,但可通过过期键通知、ZSet或Redisson实现。然而,这种方法精度有限,稳定性较差,适合轻量级需求。Redisson的RDelayedQueue提供更简单的延迟队列实现。
174 9
|
17天前
|
缓存 NoSQL 定位技术
深入探索Redis:面试中必须掌握的关键知识点
深入探索Redis:面试中必须掌握的关键知识点
|
22天前
|
NoSQL Java 测试技术
面试官:如何搭建Redis集群?
**Redis Cluster** 是从 Redis 3.0 开始引入的集群解决方案,它分散数据以减少对单个主节点的依赖,提升读写性能。16384 个槽位分配给节点,客户端通过槽位信息直接路由请求。集群是无代理、去中心化的,多数命令直接由节点处理,保持高性能。通过 `create-cluster` 工具快速搭建集群,但适用于测试环境。在生产环境,需手动配置文件,启动节点,然后使用 `redis-cli --cluster create` 分配槽位和从节点。集群动态添加删除节点、数据重新分片及故障转移涉及复杂操作,包括主从切换和槽位迁移。
31 0
面试官:如何搭建Redis集群?
|
1月前
|
运维 负载均衡 NoSQL
【大厂面试官】知道Redis集群和Redis主从有什么区别吗
集群节点之间的故障检测和Redis主从中的哨兵检测很类似,都是通过PING消息来检测的。。。面试官抓抓脑袋,继续看你的简历…得想想考点你不懂的😰。
67 1
|
1月前
|
NoSQL Redis
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
面试官:不用慌尽管说,错了也没关系。。。来说说Redis数据同步。是这样的,Redis有一个叫命令传播的概念,如果像面试官说的这种场景,再使用上面我提到的AOF缓冲区就有点浪费内存空间了。所以Redis会将主服务器的这条Del删除命令
62 2
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
|
1月前
|
NoSQL Redis 数据库
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
咳咳咳,看你简历写了精通Redis,那我就随便问问。主要有RDB持久化、AOF持久化。是这样,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。
55 1
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
|
2月前
|
缓存 NoSQL Linux
面试必备:一线大厂Redis设计规范与性能优化
本文梳理了在使用Redis过程需要遵循的一些最佳实践,包括针对架构维度的一些深入性能优化的知识,如果面试官问你:"说下在使用Redis的过程中,需要注意哪些规范?",如果你按照本文的思路回答,肯定能让面试官眼前一亮,offer自然就到手了。
52 0
面试必备:一线大厂Redis设计规范与性能优化
|
2月前
|
存储 NoSQL Java
面试官:Redis如何保证高可用?
面试官:Redis如何保证高可用?
76 2
面试官:Redis如何保证高可用?

热门文章

最新文章