Redis面试题

news2025/7/10 9:27:49

目录

面试题:谈谈你对Redis的理解?

面试题:Redis的基本数据类型

         Redis的基本数据类型以及它们的应用场景:

面试题:redis内存淘汰机制

面试题:Redis持久化机制

RDB

AOF

面试题:Redis写时复制思想的体现:

Redis持久化时如何判断数据过期?

RDB

AOF

项目中Redis的持久化机制

面试题:Redis为什么快呢?

面试题:redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

         多路 I/O 复用模型

为什么Redis是单线程的?

Redis的线程模型

在使用Redis做为缓存层的时候是怎么通过Java操作Redis的呢?

巨人的肩膀


面试题:谈谈你对Redis的理解?

  • Redis是C语言编写的一个基于内存的高性能键值对(key-value)的NoSQL数据库,一般用于架设在Java程序与数据库之间用作缓存层,为了防止DB磁盘IO效率过低造成的请求阻塞、响应缓慢等问题,用来弥补DB与Java程序之间的性能差距,同时,也可以在DB吞吐跟不上系统并发量时,避免请求直接落入DB从而起到保护DB的作用。
  • 而Redis一般除了缓存DB数据之外还可以利用它丰富的数据类型及指令来实现一些其他功能,比如:计数器、用户在线状态、排行榜、session存储等,同时Redis的性能也非常可观,通过官方给出的数据显示能够达到10w/s的QPS处理,但是在生产环境的实测结果大概读取QPS在7-9w/s,写入QPS在6-8w/s左右(注:与机器性能也有关),同时Redis也提供事务、持久化、高可用等一些机制的支持。

面试题:Redis的基本数据类型

Redis数据类型在之前是五种,但是现在的版本中存在九种,分别为常见的五种:字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(sorted sets)以及后续的四种数据类型:bitmaps、hyperloglogs、地理空间(geospatial)、消息(Streams),不过无论是哪种数据类型Redis都不会直接将它放在内存中存储,而是转而内部使用RedisObject来存储以及表示所有类型的key-value(如下图):
 
Redis内部使用一个RedisObject对象来表示所有的key和value,RedisObject最主要的信息如上图所示:type表示一个value对象具体是何种数据类型,encoding是不同数据类型在Redis内部的存储方式。比如:type=string表示value存储的是一个普通字符串,那么encoding可以是raw或者int,而关于其他数据类型的内部编码实现如下图:
 

Redis的基本数据类型以及它们的应用场景:

类型
描述
特性
场景
string
二进制安全
可以存储任何元素(数字、字符、音视频、图片、对象.....)
计数器、分布式锁、字符缓存、分布式ID生成、session共享、秒杀token、IP限流等
hash
键值对存储,类似于Map集合
适合存储对象,可以将对象属性一个个存储,更新时也可以更新单个属性,操作某一个字段
对象缓存、购物车等
list
双向链表
增删快
栈、队列、有限集合、消息队列、消息推送、阻塞队列等
set
元素不能重复,每次获取无序
添加、删除、查找的复杂度都是O(1),提供了求交集、并集、差集的操作
抽奖活动、朋友圈点赞、用户(微博好友)关注、相关关注、共同关注、好友推荐(可能认识的人)等
sorted set
有序集合,每个元素有一个对应的分数,不允许元素重复
基于分数进行排序,如果分数相等,以key值的 ascii 值进行排序
商品评价标签(好评、中评、差评等)、排行榜等
bitmaps
Bitmaps是一个字节由 8 个二进制位组成
在字符串类型上面定义的位操作
在线用户统计、用户访问统计、用户点击统计等
hyperloglog
Redis2.8.9版本添加了 HyperLogLog结构。Redis HyperLogLog是用来做基数统计的算法。
用于进行基数统计,不是集合,不保存数据,只记录数量而不是具体数据
统计独立UV等
geospatial
Redis3.2版本新增的数据类型:GEO对地理位置的支持
以将用户给定的地理位置信息储存起来, 并对这些信息进行操作
地理位置计算
stream
Redis5.0之后新增的数据类型
支持发布订阅,一对多消费
消息队列
面试的时候说下常见的五种就行,其它的自己也没深入学习。

面试题:redis内存淘汰机制

redis会在每次处理redis命令的时候判断当前redis是否达到了内存的最大限 制( 通过maxmemory配置) ,如 果达到 限制 就会触发内存淘汰机制 ,则使用对应的算法去处理需要删除的key。
maxmemory-policy:参数配置淘汰策略。maxmemory:限制内存大小( 当内存已使用率到达,则开始清理缓存)
Redis 在5.0之前为我们提供了六种淘汰策略,而5.0为我们提供了八种,但是大体上来说这些 lru、lfu、random、ttl 四种类型,如下:
策略
概述
volatile-lru
从已设置过期时间的key中挑选最近最少使用的淘汰,没有设置过期时间的key不会被淘汰,这样就可以在增加内存空间的同时保证需要持久化的数据不会丢失。
volatile-ttl
从已设置过期时间的key中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。
volatile-random
从已设置过期时间的key中任意选择数据淘汰
volatile-lfu
从已设置过期时间的key挑选使用频率最低的数据淘汰
allkeys-lru
从key中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的是全体key集合,而非过期的key集合(应用最广泛的策略)。
allkeys-lfu
从key中挑选使用频率最低的数据淘汰
allkeys-random
从key中随机选择数据淘汰
no-enviction
是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失;默认策略。
自己项目中Redis用的默认的no-enviction,设置了10分钟的缓存失效时间,本地热点缓存设置了LRU缓存策略;
由于设置redis失效时间会消耗额外的内存,如果计划避免Redis内存在此项上的浪费,可以选用allkeys-lru策略,这样就可以不再设置过期时间,高效利用内存了。
LRU是Least Recently Used的缩写,即最近最少使用。LRU源于操作系统的一种页面置换算法,选择最近最久未使用的页面予以淘汰。在Redis里,就是选择最近最久未使用的key进行删除。

面试题:Redis持久化机制

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

RDB

RDB 持久化把内存中当前进程的数据生成快照( .rdb)文件保存到硬盘的过程,有手动触发和自动触发;
手动触发时会 阻塞当前  Redis ,直到 RDB持久化过程完成为止,若内存实例比较大 会造成长时间阻塞,线上环境不建议用它
自动触发:Redis 进程创建子进程,由子进程完成持久化,阻塞时间很短(微秒级),是 save的优化,在执行 Redis-cli shutdown 关闭 Redis服务时或执行 flushall 命令时,如果没有开启 AOF 持久化,自动执行 bgsave
而且RDB 是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,重启时加载这个文件达到数据恢复。
RDB优缺点:
  • 优点:使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能;而且RDB文件存储的是压缩的二进制文件,适用于备份、全量复制,可用于灾难备份,同时RDB文件的加载速度远超于AOF文件。
  • 缺点:RDB是间隔一段时间进行持久化,如果持久化之间的时间内发生故障,会出现数据丢失。所以这种方式更适合数据要求不严谨的时候,因为RDB无法做到实时持久化,而且每次都要创建子进程,频繁创建成本过高;备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(需要的内存是原本的两倍);还有一点,RDB文件保存的二进制文件存在新老版本不兼容的问题。

AOF

AOF 持久化方式能很好的解决 RDB持久化方式造成的数据丢失, AOF持久化到硬盘中的并不是内存中的数据快照,而是记录写入命令(和 MySQLbinlog(归档日志)日志一样)
AOF持久化机制优缺点:
  • 优点:可以保证数据丢失风险降到最低,数据能够 保证是最新的,持久化是后台线程在处理,所以对于处理客户端请求的线程并不影响。
  • 缺点:文件体积由于保存的是所有命令会比RDB大上很多,而且数据恢复时也需要重新执行指令,在重启时恢复数据的时间往往会慢很多。虽然持久化并不是共用处理客户端请求线程的资源来处理的,但是这两个线程还是在共享同一台机器的资源,所以在高并发场景下也会一定受到影响。

面试题:Redis写时复制思想的体现:

简单总结一下 Redis 为什么在使用 RDB 进行快照时会通过子进程的方式(注意只有两个线程)进行实现:
在 fork 函数调用时,父进程和子进程会被分配到不同的虚拟内存空间中,所以在两个进程看来它们访问的是不同的内存。
fork子进程时,我们只为其生成虚拟空间,但是并不先为每个部分分配真实的物理空间,而是让每个虚拟空间部分仍然指向父进程的物理空间,所以父子进程共享了物理上的内存空间。只有当父进程或子进程修改相应的共享内存空间时,对被写入的内存共享才结束同时会为子进程分配真实物理空间,并把父进程的物理空间内容进行复制。这就是所谓的写时复制,即把内存的复制延迟到了内存写入的时刻。减少了快照持久化时的内存消耗同时节省了不少时间。
注意, 父子进程共享的空间粒度是页,共享的内存才会以页为单位进行拷贝,父进程会保留原有的物理空间,而子进程会使用拷贝后的新物理空间; 这样,如果当子进程运行期间,父子进程都没有修改数据,这也就避免了大量拷贝内存而带来的 时间消耗和空间占用问题。
Redis写时复制的好处:
写时拷贝的主要作用就是将拷贝推迟到写操作真正发生时,这也就避免了大量无意义的拷贝操作。
在 Redis 作为中间件服务过程中,子进程只会读取共享内存中的数据,它并不会执行任何写操作,只有父进程会在写入时才会触发写时复制机制,而对于大多数的 Redis 服务或者数据库,写请求往往都是远小于读请求的,所以使用 fork 加上写时拷贝这一机制能够带来非常好的性能,也让自动触发这一操作的实现变得非常简单。
Redis写时拷贝(COW)总结 - 掘金 ---这篇文章把redis写时复制写的很厉害

Redis持久化时如何判断数据过期?

RDB

从内存数据库持久化数据到RDB文件:持久化key之前,会检查是否过期,过期的key不进入RDB文件;
从RDB文件恢复数据到内存数据库:数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)。

AOF

从内存数据库持久化数据到AOF文件:

当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入AOF文件的,因为没有发生修改命令) 
当key过期后,在发生删除操作时,程序会向aof文件追加一条删除命令(在将来的以AOF文件恢复数据的时候该过期的键就会被删掉) 

AOF重写:

重写时,会先判断key是否过期,已过期的key不会重写到AOF文件

项目中Redis的持久化机制

项目中使用默认的RDB方式; 项目中考虑到了 Redis 中仅仅只是用来做缓存 ,虽然 RDB 因为并不是实时的持久化,会出现数据丢失,但项目的场景是可以容忍一定的数据丢失的。

面试题:Redis为什么快呢?

Redis到底有多快?

Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。
Redis快的原因嘛其实可以从多个维度来看待:
  • 一、Redis完全基于内存
  • 二、Redis整个结构类似于HashMap,查找和操作复杂度为O(1),不需要和MySQL查找数据一样需要产生随机磁盘IO或者全表查询
  • 三、Redis对于客户端的请求处理是单线程的,采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的           切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
  • 四、底层采用select/epoll多路复用的高效非阻塞IO模型
  • 五、客户端通信协议采用RESP,简单易读,避免了复杂请求的解析开销

面试题:redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

多路 I/O 复用模型

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。
采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),同时 非阻塞 IO 意味着线程在读写 IO 时可以不必再阻塞了,读写可以瞬间完成然后线程可以继续干别的事了。且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。

为什么Redis是单线程的?

官方表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。 但是,我们使用单线程的方式是无法发挥多核CPU 性能,不过我们可以通过在单机开多个Redis 实例来完善!
警告1:这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!例如Redis进行持久化的时候会以子进程或者子线程的方式执行(具体是子线程还是子进程待读者深入研究);
警告2: 从Redis 4.0版本开始会支持多线程的方式,但是,只是在某一些网络数据读写等操作上进行多线程的操作!
注意:CPU 是一个重要的影响因素,由于是单线程模型,Redis 更喜欢大缓存快速 CPU, 而不是多核。

Redis的线程模型

问这个原理性的问题,可以结合着图来给面试官讲这个问题,边想图边讲最有说服力
redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,将产生事件的 socket 压入内存队列中,事件分派器根据 socket 上的事件类型来选择对应的事件处理器进行处理。
文件事件处理器的结构包含 4 个部分:
  • 多个 socket
  • IO 多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个 socket,会将产生事件的 socket 放入队列中排队,事件分派器每次从队列中取出一个 socket,根据 socket 的事件类型交给对应的事件处理器进行处理。
要明白,通信是通过 socket 来完成的; 客户端 socket向 redis 进程的 server socket 请求建立连接,然后进行通信
Redis多线程
Redis6 版本中引入了多线程。上边已经提到过 Redis 单线程处理有着很快的速度,那为什么还要引入多线程呢?单线程的瓶颈在什么地方?
我们先来看第二个问题,在 Redis 中,单线程的性能瓶颈主要在网络IO操作上。也就是在读写网络 read/write 系统调用执行期间会占用大部分 CPU 时间。如果你要对一些大的键值对进行删除操作的话,在短时间内是删不完的,那么对于单线程来说就会阻塞后边的操作。
Redis 在设计上采用将网络数据读写和协议解析通过多线程的方式来处理,对于命令执行来说,仍然使用单线程操作。

在使用Redis做为缓存层的时候是怎么通过Java操作Redis的呢?

使用spring中的RedisTemplate。

巨人的肩膀

Redis综述篇:与面试官彻夜长谈Redis缓存、持久化、淘汰机制、哨兵、集群底层原理! - 掘金

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/5714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

相似度系列-3:传统方法ROUGE ROUGE: A Package for Automatic Evaluation of Summaries

文章目录ROUGE: A Package for Automatic Evaluation of Summariesintroduction基础模型Rouge-NRouge_NmultiROUGE-L: Longest Common Subs equence1**Sentence-level LCS**2**Summary-Level LCS**ROUGE-W: Weighted Longest Common SubsequenceROUGE-S: Skip-Bigram Co-Occurr…

Python小总结

Python小总结一、open(一)open的定义:open是Python的内置函数,一般用于本地文件的读写操作。(二)open例子:二、with open(一)用途:with open是Python用来打开…

04 数学软件与建模---最优化模型

一、优化模型的数学描述 二、优化模型的分类 1.根据是否存在约束条件 有约束问题和无约束问题。 2.根据设计变量的性质 静态问题和动态问题。 3.根据目标函数和约束条件表达式的性质 线性规划,非线性规划,二…

PiL测试实战(上)| 模型生成代码的单元级PiL测试

前言 对于嵌入式代码,为了测试软件能否在目标芯片上实现预期的功能,通常需要进行PiL测试(Processor-in-the-Loop-Testing)。 目前市面上较为常见的嵌入式软件调试工具有PLS UDE和LAUTERBACH Trace32等。UDE和Trace32可以很好的完…

通俗易懂话GC-C#的内存管理

昨天和一个朋友聊到图像处理软件内存占用多的问题,然后很自然聊到了GC,回想起以往很初学者都问到类似的问题: 1、C#自己就会垃圾回收,为什么我还要关心垃圾回收? 2、GC可以回收垃圾,但回收的时候又会让线…

js深浅拷贝:保证赋值后改变第二个变量的值,不影响第一个变量的值

对于基本数据来说,将一个变量赋值给另一个变量,第二个变量值改变了,不会影响第一个变量;但对于复杂类型中的对象来讲,将一个对象赋值给另外一个对象,其实是将放对象内容的地址赋值给了第二个对象&#xff0…

Amazon EKS绑定alb 使用aws-load-balancer-controller(Ingress Controller)对外提供服务

1、创建AWS Load Balancer Controller 的 IAM 策略 亚马逊相关文档 下载地址 打开 策略 点击 创建策略 打开 IAM_Policy.json 复制内容粘贴到 json 点击下一步:标签 然后一直下一步 在下图中名称填写 AWSLoadBalancerControllerIAMPolicy 你也可以自定义名称。然后创建策略。…

尚医通_第11章_医院排班管理和搭建用户系统环境

尚医通_第11章_医院排班管理和搭建用户系统环境 文章目录尚医通_第11章_医院排班管理和搭建用户系统环境第一节、-医院排班管理需求分析一、医院排班管理需求1、页面效果2、接口分析第二节、医院排班管理-科室列表一、科室列表(接口)1、添加service接口和…

李峋同款爱心代码

李峋爱心代码背景代码运行pycharm打包成exe程序背景 最近大火的电视剧《点燃我温暖你》出现,令我的家庭地位进一步下降,因为男主“李峋”已经变成了她的大老公,而我就被打入冷宫. 为了满足她的“攀比心”,我连夜给她实现了粉红色爱…

第十节:多态【java】

目录 🍀1.多态 📖1.1 多态的概念 📒1.2 多态实现条件 👆1.2.1向上转型 💯1.2.2重写 🔱1.2.3动态绑定和静态绑定 🌈1.2.4多态的应用 👇1.2.5向下转型 📕1.3多态的…

Java岗面试核心NIO有关知识总结

这篇文章主要是阅读了一些关于NIO的文章,对一些重要的部分进行了摘取总结。BIO、NIO、AIO的不同 BIO:同步阻塞IO模式,线程发起IO请求后,一直阻塞IO,直到缓冲区数据就绪后,再进行下一步操作。NIO&#xff1a…

SpringCloud基础知识【Hystrix熔断器】

SpringCloud基础知识【Hystrix熔断器】1. Hystrix概述2. Hystix-隔离2.1 线程池隔离2.2 信号量隔离2.3 Hystix隔离小结3. Hystix-降级3.1 服务提供方降级3.2 消费方降级3.3 Hystix降级小结4. Hystix-熔断4.1 代码演示4.1 熔断监控5. Hystix-限流1. Hystrix概述 Hystix&#xf…

基于概率距离削减法、蒙特卡洛削减法的风光场景不确定性削减(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

一文带你吃透数据库的约束,不做CRUD程序员

在SQL标准中,一共规定了6种不同的约束,包括非空约束,唯一约束和检查约束等,而在MySQL中是不支持检查约束的,所以这篇文章先对其余5种约束做一个详解和练习。 文章目录1. 约束的概念2. 约束的分类3. 非空约束4. 唯一约束…

.net 大型物流综合管理网络平台源码【免费分享】

淘源码:国内专业的免费源码下载平台 源码分享,需要源码学习可私信我! 一、源码描述 这是一款大型的物流综合管理网络平台源码,十分完整实用,便于调试,涵盖了物流综合管理的全面内容,该源码运行比…

单商户商城系统功能拆解30—营销中心—积分签到

单商户商城系统,也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法,例如拼团,秒杀,砍价,包邮…

【负荷预测】基于改进灰狼算法(IGWO)优化的LSSVM进行负荷预测(Matlab代码实现)

📝个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,…

IDEA 中Git 多次 Commit 合并为一次提交

一、背景 由于个人习惯的原因,喜欢一个功能分多次提交,导致很多提交比较零碎。 有时候经常需要将零碎的提交合并成一次,该怎么办? 可以使用 IDEA 自带的 Git 插件 将多次 Commit 合并成一次。 二、问题描述 如希望将第二次到第…

新品上市 | “电子表格软件”轻装上阵,企业报表用户的新选择

2022年11月14日,恰逢思迈特软件11周年的生日,我们更新了电子表格软件(Smartbi Spreadsheet),希望在一站式BI产品之外,更多的企业用户可以通过成熟、可控、小巧、灵活的报表工具,提升数据化管理的…

分击合进,锦江之星酒店与白玉兰酒店再领投资热潮

2022年11月11日,「山水画中游,暇享好时光」品牌品鉴会在广西桂林隆重召开。锦江酒店(中国区)旗下两大酒店品牌锦江之星酒店和白玉兰酒店携手亮相本次活动。 (品牌矩阵品鉴会活动现场) 后疫情时代&#xff…