当前位置:首页 > 服务端 > Redis高频面试题汇总(2021最新版)

Redis高频面试题汇总(2021最新版)

2022年09月16日 08:58:49服务端4

此时此刻面试官内心想发大致是这样的:

  • 比较基础,应该没有很深入的了解过Redis

  • 想问题停留在表面呀,估计平时就知道干活,没想过问题

  • 给你自由发挥的机会,你不把握呀,看样子还是得我自己来,先问你几个分布式、持久化的问题看看水平怎么样,不行就这样了吧,后面还有好多人,等会要下班了。

如果不想硬抗下面试官的降龙十八掌,就应该主动挑起面试官的兴趣,并且把自己的格局(水平广度和深度)率先提升起来,将自己会的东西尽可能的多讲一些出来。 ​

比如以下这种回答方式:

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

Redis面试题汇总


Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

高性能:高性能一个很大的标准,就是响应时间快。Redis基于内存存储,CPU访问速度快,此外Redis对于数据结构的极致优化、内部线程模型和网络I/O模型的设计,决定了Redis是一个高性能存储数据库。唯一的缺点就是内存比较昂贵,通常情况下资源比较有限,因此对于非常大的数据缓存架构应该合理设计,我们通常不会在Redis中存放过大的数据,因为这样会导致Redis性能下降。

高并发:高并发通常指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second)和并发用户数等,Redis虽然它是一个单进程单线程模型,但是Redis确实高并发业务场景下的一把利器,目前Redis的QPS已经能达到10万甚至是100万级别了,这是绝对的高并发。

高可用:Redis高可用主要体现在主从复制、sentinel(哨兵模式)和Cluster(集群模式)三者 ​

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

Redis的单线程指的是执行命令操作使用单线程,Redis6.x发布之后使用多线程处理网络数据的读写和协议解析,Redis单线程这么快的原因主要有这些点:

  • 采用I/O多路复用非阻塞模型处理客户端socket连接,能够极大的优化Redis服务端响应速度和效率,多路 I/O 复用技术可以让单个线程高效的处理多个连接请求,尽量减少网络 IO 的时间消耗。

  • 基于内存存储,减少磁盘IO,读取速度快

  • Redis对内部数据结构做了极致的优化,使Redis的数据结构非常高效。并且在不同的数据量和存储内容采取不同的编码方式,这就涉及到了 Redis 底层的编码转换。比如list、hash、zset 三个键使用到了 ziplist 压缩列表编码,ziplist 是一种结构紧凑的数据结构,当某一键值中所包含的元素较少时,会优先存储在 ziplist 中,当元素个数超过某一值后,才将 ziplist 转化为标准存储结构,当然这一值是在redis.conf中可自定义配置。此外SDS的内存预分配、Hash结果Rehash中的渐进式hash、ZSet顺序基于SkipList存储,都优化了数据结构,使其更快。

  • Redis在执行命令操作使用单线程,无需考虑并发锁的设计,以及多线程带来的CPU上下文切换消耗,因此执行命令更快

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

Redis有5种基本数据类型它们分别是String、List、Hash、Set、ZSet;此外还有三种特殊数据类型Bitmaps、Geospatial、HyperLogLog

| 数据类型 | 简单描述 | 使用场景 |

| — | — | — |

| String | string(字符串)是Redis最简单也是使用最广泛的数据结构,它的内部是一个字符数组。String(字符串)是动态字符串,允许修改;它在结构上的实现类似于Java中的ArrayList(默认构造一个大小为10的初始数组),这是冗余分配内存的思想,也称为预分配;这种思想可以减少扩容带来的性能消耗。当string(字符串)的大小达到扩容阈值时,将会对string(字符串)进行扩容,string(字符串)的扩容主要有三种情况:1.长度小于1MB,扩容后为原先的两倍; length = length * 2 2.长度大于1MB,扩容后增加1MB; length = length + 1MB 3. 字符串的长度最大值为 512MB | 缓存、计数器、分布式锁等。 |

| List | Redis的列表相当于Java语言中的LinkedList,它是一个双向链表数据结构(但是这个结构设计比较巧妙,后面会介绍),支持前后顺序遍历。链表结构插入和删除操作快,时间复杂度O(1),查询慢,时间复杂度O(n)。Redis的list(列表)不是一个简单。LinkedList,而是quicklist ——“快速列表”,quicklist是多个ziplist(压缩列表)组成的双向列表; | 链表、异步队列、微博关注人时间轴列表…… |

| Hash | Redis的hash(字典)相当于Java语言中的HashMap,它是根据散列值分布的无序字典,内部的元素是通过键值对的方式存储。hash(字典)的实现与Java中的HashMap(JDK1.7)的结构也是一致的,它的数据结构也是数组+链表组成的二维结构,节点元素散列在数组上,如果发生hash碰撞则使用链表串联在数组节点上。Redis中的hash(字典)存储的value只能是字符串值,此外扩容与Java中的HashMap也不同。Java中的HashMap在扩容的时候是一次性完成的,而Redis考虑到其核心存取是单线程的性能问题,为了追求高性能,因而采取了渐进式rehash策略。渐进式rehash指的是并非一次性完成,它是多次完成的,因此需要保留旧的hash结构,所以Redis中的hash(字典)会存在新旧两个hash结构,在rehash结束后也就是旧hash的值全部搬迁到新hash之后,新的hash在功能上才会完全替代以前的hash。 | 用户信息、Hash 表…… |

| Set | Redis的set(集合)相当于Java语言里的HashSet,它内部的键值对是无序的、唯一的。它的内部实现了一个所有value为null的特殊字典。集合中的最后一个元素被移除之后,数据结构被自动删除,内存被回收。 | 去重功能、赞、踩、共同好友…… |

| ZSet | zset(有序集合)是Redis中最常问的数据结构。它类似于Java语言中的SortedSet和HashMap的结合体,它一方面通过set来保证内部value值的唯一性,另一方面通过value的score(权重)来进行排序。这个排序的功能是通过Skip List(跳跃列表)来实现的。zset(有序集合)的最后一个元素value被移除后,数据结构被自动删除,内存被回收。 | 粉丝列表、学生成绩排序、访问量排行榜、点击量排行榜…… |

| Bitmaps | Bitmaps 称为位图,严格来说它不是一种数据类型。Bitmaps底层就是字符串(key-value)byte数组。我们可以使用普通的get/set直接获取和设值位图的内容,也可以通过Redis提供的位图操作getbit/setbit等将byte数组看成“位数组”来处理。Bitmaps 的“位数组”每个单元格只能存储0和1,数组的下标在Bitmaps中称为偏移量。Bitmaps设置时key不存在会自动生成一个新的字符串,如果设置的偏移量超出了现有内容的范围,就会自动将位数组进行零扩充 | 员工打卡…… |

| Geospatial | Geospatial是Redis在3.2版本以后增加的地理位置GEO模块 | 微信附近的人,在线点餐“附近的餐馆”…… |

| HyperLogLog | HyperLogLog是用来做基数统计的算法,它提供不精确的去重计数方案(这个不精确并不是非常不精确),标准误差是0.81%,对于UV这种统计来说这样的误差范围是被允许的。HyperLogLog的优点在于,输入元素的数量或者体积非常大时,基数计算的存储空间是固定的。在Redis中,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同的基数。但是HyperLogLog只能统计基数的大小(也就是数据集的大小,集合的个数),他不能存储元素的本身,不能向set集合那样存储元素本身,也就是说无法返回元素。 | 基数统计比如UV等 |

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

Redis的数据结构均可以通过EXPIRE key seconds 的方式设置key的过期时间(TTL)。我们也习惯的认为Redis的key过期时间到了,就会自动删除,显然这种想法并不正确。Redis的设计考虑到性能/内存等综合因素,设计了一套过期策略。

  • 主动删除(惰性删除)

  • 被动删除(定期策略)

主动删除(惰性删除)指的是当key被访问的时候,先校验key是否过期,如果过期了则主动删除。 被动删除(定期策略)指的是Redis服务器定时随机的测试key的过期时间,如果过期了则被动删除。被动删除的存在必不可少,因为存在一些过期且永久不在访问的key,如果都依赖主动删除,那么它们将会永久占用内存。 Redis为了保证提供高性能服务,被动删除过期的key,采用了贪心策略/概率算法,默认每隔10秒扫描一次,具体策略如下:

  1. 从过期字典(设置了过期时间的key的集合)中随机选择20个key,检查其是否过期

  2. 删除其中已经过期的key

  3. 如果删除的过期key数量大于25%,则重复步骤1

此外开发在设计Redis缓存架构时,一定要注意要尽可能的避免(禁止)将大量的key设置为同一过期时间,因为结合被动删除可知,Redis被动删除过期key时,会导致服务短暂的不可用;如果存在大量key同时过期,这会导致被动删除key的三个步骤循环多次,从而导致Redis服务出现卡顿情况,这种情况在大型流量项目是无法接收的。 因此为了避免这种情况出现,一定要将一些允许过期时间不需要非常精确的key,设置较为随机的过期时间,这样就可以将卡顿时间缩小。 ​

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

在分布式场景中我们常见的分布式锁解决方案有(如果自己都会可以把其他两种也在这带出来,如果不会那就别把自己坑了呀!):

  1. 基于数据库锁机制实现的分布式锁

  2. 基于Zookeeper实现的分布式锁

  3. 基于Redis实现的分布式锁

而关于Redis实现分布式锁的方案是这样的。 如果Redis是在单机环境中我们可以通过,Redis提供的原子指令来实现分布式锁

set key value [EX seconds] [PX milliseconds] [NX|XX]

为了防止A加的锁,被B删除了,可以加锁时传入客户端加锁标记,只有当客户端传入的标记和锁标记相同时才允许解锁,不过Redis并未提供这样的功能,我们只能通过Lua脚本来处理,因为Lua脚本可以保证多个指令的原子性执行。最后我们还要考虑锁的超时问题,如果客户端一直不释放锁肯定也是不行的,因此锁只能保证在指定的超时时间范围内不被其他客户端解锁,超时之后就自动释放了,这种情况很难我们可以这样优化:

  1. 尽可 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 能不要在Redis分布式锁中执行较长的任务,尽可能的缩小锁区间内执行代码,就像单JVM锁中的synchronized优化一样,我们可以考虑优化锁的区间

  2. 多做压力测试和线上真实场景的模拟测试,估算一个合适的锁超时时间

  3. 做好Redis分布式锁超时任务未执行完的问题发生后,数据恢复手段的准备

如果是在分布式环境中,会增加一个新的问题,比如sentinel+一主多从环境中,可能存在客户端在主节点上申请了锁,但是同步未完成,主节点宕机了,此时新选举的主节点上锁是失效的。 对于这种情况的处理应该是这么考虑的,首先Redis主从同步直接无论如何都无法解决数据会有丢失的情况。所以我们考虑把像一个Redis申请锁,变成像多个单机Redis申请锁,只有大部分申请成功就行。这种思想就是RedLock(红锁)。 RedLock通过使用多个Redis实例,各个实例之间没有主从关系,相互独立;加锁的时候,客户端向所有的节点发送加锁指令,如果过半的节点set成功,就加锁成功。释放锁时,需要向所有的节点发送del指令来释放锁。 红锁虽然解决了主从同步的问题,但是带来新的复杂问题:

  • 第一个问题是时钟漂移

  • 第二个问题是客户端像不同的Redis服务端申请锁成功的时间是不同的

因此在RedLock中需要计算申请的锁的最小有效时长。假设客户端申请锁成功,第一个key设置成功的时间为TF,最后一个key设置成功的时间为TL,锁的超时时间为TTL,不同进程之间的时钟差异为CLOCK_DIFF,则锁的最小有效时长是:

TIME = TTL - (TF- TL) - CLOCK_DIFF

采用Redis来实现分布式锁,离不开服务器宕机等不可用问题,这里RedLock红锁也一样,即使是多台服务器申请锁,我们也要考虑服务器宕机后的处理,官方建议采用AOF持久化处理。 但是AOF持久化只对正常SHUTDOWN这种指令能做到重启恢复,但是如果是断电的情况,可能导致最后一次持久化到断电期间的锁数据丢失,当服务器重启后,可能会出现分布式锁语义错误的情况。所以为了规避这种情况,官方建议Redis服务重启后,一个最大客户端TTL时间内该Redis服务不可用(不提供申请锁的服务),这确实可以解决问题,但是显而易见这肯定影响Redis服务器的性能,并且在多数节点都出现这种情况的时候,系统将出现全局不可用的状态。 ​

Redis高频面试题汇总(2021最新版) _ JavaClub全栈架构师技术笔记

这个我的理解大致是这样的面试官!!

Redis的非常快,很大一部分原因是因为Redis的数据存储在内存中,既然在内存中,那么当服务器宕机或者断电的时候,数据就会全部丢失了,所以Redis提供了两种机制来保证Redis数据不会因为故障而全部丢失,这种机制称为Redis的持久化机制。 Redis的持久化机制有两种:

  • RDB(Redis Data Base) 内存快照

  • AOF(Append Only File) 增量日志

RDB(Redis DataBase) 指的是在指定的时间间隔内将内存中的数据集快照写入磁盘,RDB是内存快照(内存数据的二进制序列化形式)的方式持久化,每次都是从Redis中生成一个快照进行数据的全量备份。 优点:

  • 存储紧凑,节省内存空间

  • 恢复速度非常快

  • 适合全量备份、全量复制的场景,经常用于灾难恢复(对数据的完整性和一致性要求相对较低的场合)

缺点:

  • 容易丢失数据,容易丢失两次快照之间Redis服务器中变化的数据。

  • RDB通过fork子进程对内存快照进行全量备份,是一个重量级操作,频繁执行成本高。

  • fork子进程,虽然共享内存,但是如果备份时内存被修改,最大可能膨胀到2倍大小。

RDB触发的规则分为两大类,分别是手动触发和自动触发: 自动触发:

  1. 配置触发规则

  2. shutdown触发

  3. flushall触发

手动触发:

  1. save

  2. bgsave

**AOF(Append Only File)**是把所有对内存进行修改的指令(写操作)以独立日志文件的方式进行记录,重启时通过执行AOF文件中的Redis命令来恢复数据。AOF能够解决数据持久化实时性问题,是现在Redis持久化机制中主流的持久化方案(后续会谈到4.0以后的混合持久化)。 优点:

  • 数据的备份更加完整,丢失数据的概率更低,适合对数据完整性要求高的场景

  • 日志文件可读,AOF可操作性更强,可通过操作日志文件进行修复

缺点:

  • AOF日志记录在长期运行中逐渐庞大,恢复起来非常耗时,需要定期对AOF日志进行瘦身处理(后续详述)

  • 恢复备份速度比较慢

  • 同步写操作频繁会带来性能压力

AOF日志是以文件的形式存在的,当程序对AOF日志文件进行写操作时,实际上将内容写到了内核为文件描述符分配的一个内存缓冲区中,随后内核会异步的将缓冲区中的数据刷新到磁盘中。如果缓冲区中的数据没来得及刷回磁盘时,服务器宕机了,这些数据就会丢失。 因此Redis通过调用Linux操作系统的glibc提供的fsync(int fid)来将指定文件的内容强制从内核缓冲区刷回磁盘,以此来保证缓冲区中的数据不会丢失。不过这是一个IO操作,相比Redis的性能来说它是非常慢的,所以不能频繁的执行。 Redis配置文件中有三种刷新缓冲区的配置:

作者:普通网友
来源链接:https://blog.csdn.net/m0_69526738/article/details/124472020

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/41663.html

标签: Redis面试题
分享给朋友:

“Redis高频面试题汇总(2021最新版)” 的相关文章

Redis面试题整理(有pdf版)

1、什么是 Redis?简述它的优缺点? Redis 的全称是:Remote Dictionary.Server,本质上是一个 Key-Value 类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬...

35个Redis面试题

35个Redis面试题

      1.什么是redis? Redis 是一个基于内存的高性能key-value数据库。 2.Reids的特点   Redis本质上是一个Key-Value类型的内存数据库,很像memc...

Redis的常见面试题(全)

Redis的常见面试题(全)

目录 前言 1. 了解一下你认识的Redis 2. Redis的适用场景 3. Redis的线程机制 4. Redis单线程,如何提高多核cpu利用率 5. Redis持久化机制...

2020年最新Redis面试题

2020年最新Redis面试题

什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。 Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为...

三、后端开发2021面试题总结JAVA_JVM_Redis_ZooKeeper

2021年初面试总结:JAVA_JVM_Redis_ZooKeeper 以下问题是对本人在2021.01.27到2021.02.08这段时间面试过的一些互联网、传统型、初创型公司的技术问题整理。建议小伙伴们在面试前一定不要着急,先静下心来让把下面的面试题或者自...

redis面试题及答案

1、什么是Redis? Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒...

2021-05-14 Redis面试题 如何选择合适的持久化方式?

如何选择合适的持久化方式? 1、一般来说, 如果想达到足以媲美PostgreSQL的数据安全性,你应该同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比R...

2021最新 Redis面试题精选(附刷题小程序)

2021最新 Redis面试题精选(附刷题小程序)

精选Redis常见面试题50题,包含了基础知识、集群、并发、优化等各个方面,便于快速巩固、复习知识点; 祝找到理想的工作。 推荐使用小程序阅读 为了能让您更加方便的阅读 本文所有的面试题目均已整理至小程序《面试手册》 可以通过微信扫描(或长按)下图的二维码享受更...

深入理解Redis,以Redis面试题来复习;Java程序员面试必备宝典

深入理解Redis,以Redis面试题来复习;Java程序员面试必备宝典

本文转载自:深入理解Redis,以Redis面试题来复习;Java程序员面试必备宝典 前言 没得前言,因为懒,都是面试题、书籍和学习资料,自己看! 一. Redis面试真题 1. 什么是 Redis?简述它的优缺点?...

Redis常见面试题

Redis常见面试题

介绍:Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。 传统数据库遵循 ACID 规则。而 Nosql(Not Only SQL 的缩写,是对不...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。