新增:

标题链接
MySql面试16连问https://blog.csdn.net/m0_52256357/article/details/126497432?spm=1001.2014.3001.5501

.

10道经典Redis面试题

1、什么是redis?它有什么特点?

答:
redis是一个开源的、支持数据持久化和备份的key-value数据库。
①Redis的数据是存在内存中的,读写速度非常快。
②redis支持数据持久化,可以将内存中的数据存储到磁盘中,重启redis的时候可以再次加载进行使用。
③redis不仅支持key-value数据结构,还提供set、list、hash等数据结构的存储
④redis支持数据备份,即master-slave模式的数据备份

·
·

2、redis的数据类型有哪些?分别介绍一下

Redis有五种基本的数据类型:String、Set、List、Hash、Zset
和三种特殊的数据类型:Geospatial、Hyperloglog、Bitmap
在这里插入图片描述
①String
String是Redis最基础的数据结构,它是二进制安全的,可以存储图片或序列化的对象,值最大存储为512M。
String的数据结构是简单动态字符串SDS,内部结构采用预分配冗余空间的方式来减少内存的频繁分配。
·

②List
List用来存储多个有序的字符串,按照插入顺序排序,底层实际上是个双向链表
List的数据结构是ziplist压缩列表和quicklist快速列表。Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余
·

③Set
Set也是用来存储多个字符串的,但set可以自动排重,当需要存储多个元素,又不希望出现重复数据时,可以选择stet。
Set的数据结构是dict字典,而字典是用哈希表实现的,set中所有value都指向同一个内部值。
·

④Hash
Hash用来存储键值对,是一个String类型的field和value的映射表,适合用来存储对象。
Hash的数据结构是ziplist和hashtable,当存储的元素较少时使用ziplist,反之使用hashtable
在这里插入图片描述

⑤Zset
Zset是已排序的、无重复的字符串集合,Zset中的每个元素都关联了一个评分score,这个score被用来从最低分到最高分来排序集合中的元素。
Zset的数据结构是ziplist和跳跃表skiplist。
·
·

String和Hash的对比:
在这里插入图片描述
·
·

三种特殊的数据类型:
Geospatial:用于存储地理位置信息,并对存储的信息进行操作。
HyperLogLog:用来做基数统计算法的数据结构,如统计网站的UV。
Bitmaps:用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组

·

·

3、简述redis事务

①定义:redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
②Redis 事务中有 Multi、Exec 和 discard 三个指令,在 Redis 中,从输入 Multi 命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入 Exec 后,Redis 会将之前的命令队列中的命令依次执行。而组队的过程中可以通过 discard 来放弃组队。
③redis 不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误。
·

·

4、redis事务的乐观锁和悲观锁是怎样的?

①悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会被阻塞,直到它拿到锁。
②乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量

·

·

5、redis的持久化操作RDB

①定义:在指定时间间隔内,将内存中的数据集快照写入磁盘中,其实际工作过程是,先创建一个子进程,将数据集写入一个临时文件,写入成功后,再替换掉之前的文件,用二进制压缩存储

②优点:
1、方便持久化和备份
2、RDB创建子进程完成写操作,而主进程继续处理命令,IO最大化、保证redis的高性能
3、当数据集较大时,RDB的骑当效率比AOF更高

③缺点:
1、数据安全性低,因为RDB是隔一段时间才进行持久化,如果在这个间隔期间发生了故障,那么这期间的数据将会丢失。
2、当数据集较大时,可能会导致服务器停止服务几百毫秒

·

·

6、redis的持久化操作AOF

①定义:用日志的形式记录服务器所处理的每一个写、删除操作,查询操作不记录,用文本的方式进行记录,可以打开文件看到详细的操作记录。在重新启动redis时,redis会根据日志文件的内容将指令从前到后执行一次。

②优点:
1、AOF有三种同步策略,数据安全性比RDB高。
2、AOF通过append模式写文件,即使中途服务器宕机也不会破坏已存在的内容
3、AOF有rewrite模式,定期对AOF文件进行重写,来达到压缩的目的

③缺点:
AOF文件比RDB文件大,且恢复速度慢,运行效率比RDB低,不适用于数据集大的时候
若AOF和RDB同时开启,系统会默认取AOF中的数据

·

·

7、redis的过期键删除策略

我们可以设置redis中key的过期时间,若不设置,默认永不过期。Redis的过期策略就是当key过期时,redis如何处理。
①惰性过期:只有当访问了一个key时,才会判断该key是否有过期,过期则清除。该策略可以最大化节省CPU资源,但可能存在大量过期的key,未被再次访问,无法清除,而占用内存。
②定期过期:每隔一定时间,会扫描expires字典中一定数量的key,若过期则清除。该策略可以使cpu和内存资源达到平衡的效果
【redis中expires字典会存储所有设置了过期时间的key】
Redis中同时使用了惰性过期和定期过期两种过期策略

·

·

8、Redis为什么快?

①redis是基于内存存储实现的数据库,相比于数据存在磁盘的mysql,可以省去磁盘io的消耗。
②redis支持多种数据类型和数据结构,合理的数据结构使得程序执行速度快
③实现了I/O多路复用:一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu
【文件句柄在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄】
④redis实单线程模型,避免了CPU不必要的上下文切换和竞争锁的消耗。
⑤redis构建了虚拟内存机制,即把冷数据从内存交换到磁盘中,腾出内存空间用于热数据,节约系统调用时间

·

·

9、redis的集群方案【3种】

①主从复制:
1、模式:
主从复制模式包含一个主数据库,一个或多个从数据库。客户端可以对主数据库进行读写操作,对从数据库只能进行读操作,主数据库写入的数据会实时自动同步给从数据库。
2、具体步骤:
①slave启动后,向master发送同步命令,master接收到同步命令后通过bgsave命令保存快照,并使用缓冲区记录保存快照这段时间内执行的写命令。
②master将保存的快照文件发送给slave,并继续记录执行的写命令。
③slave接收到快照文件后,加载快照文件,载入数据。
④master快照发送完后开始向slave发送缓冲区的写命令,slave接收命令并执行,完成复制初始化。
⑤此后master每次执行一个写命令都会同步发送给slave,保持master与slave之间数据的一致性
3、优点:
①master能自动将数据同步到slave,并且读写分离,可以分担master的读的压力。
②master和slave之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以处理客户端请求。
4、缺点:
①不具备自动容错与恢复功能,master或slave的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端IP才能恢复。
②master宕机,如果宕机前数据没有同步完,则切换IP后会存在数据不一致的问题。

·

②哨兵模式:
1、模式:
哨兵模式基于主从复制模式,只是引入了哨兵来监控与自动处理故障,当一个 master 宕机后,会从从服务器中选一个作为主机。如果只有一个哨兵进程对Redis服务器进行监控,当这个哨兵宕机后,就没办法对主服务器进行监控了,因此,我们一般使用多个哨兵进行监控。各个哨兵之间还会相互监控,这样就形成了多哨兵模式。
2、具体步骤:
①假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover[故障转移]过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。
②当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票。
③投票的结果由一个哨兵发起,进行failover[故障转移]操作。
④切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线
3、优点:
①哨兵集群,基于主从复制模式,所有的主从配置优点,它全有。
②主从可以切换,故障可以转移,系统的可用性就会更好。
③哨兵模式就是主从模式的升级,手动到自动,更加健壮。
4、缺点:
①难以支持在线扩容,Redis的容量受限于单机配置。
②实现哨兵模式的配置很复杂,并且需要额外的资源来启动哨兵进程。

·

③Cluster模式:
1、模式:
①Cluster模式实现了Redis的分布式存储,即每台节点存储不同的内容,来解决在线扩容的问题
②所有的redis节点相互连接,内部使用二进制协议优化传输速度和带宽。
③客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。(当Redis节点收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis节点地址返回给客户端,客户端收到后自动将原请求重新发往这个地址)
2、描述:
①一个 Redis 集群包含16384个插槽,数据库中的每个键都属于这 16384 个插槽的其中一个,Redis的每个节点,都负责维护一部分插槽。
②当我们存取key的时候,Redis会根据CRC16的算法得出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,通过这个编号,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
③Cluster模式也引入了主从复制模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点都宕机了,那么该集群就无法再提供服务了。
④Cluster模式集群节点最小配置6个节点(3主3从,因为需要半数以上),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
3、优点:
①可线性扩展到1000多个节点,节点可动态添加或删除。
②能够实现自动故障转移。
4、缺点:
①数据通过异步复制,不保证数据的强一致性。
②slave只是备用,不能缓解“读操作”的压力。
③不支持多数据库空间,单机redis可以支持16个db,集群模式下只能使用一个,即db0
④对于像批量操作、事务操作等的支持性不够好。
·

·

10、缓存穿透、缓存击穿、缓存雪崩

1. 缓存雪崩:
Redis中的缓存数据是有过期时间的,当在同一时间大量的缓存同时失效时,由于大量请求无法在redis缓存中处理,就会发送到数据库,导致数据库压力激增,可能会导致数据库崩溃,从而导致整个系统崩溃。
解决缓存雪崩的关键:避免Redis的缓存在短时间内大量的过期
解决方案:
①根据业务需要来合理的设置过期的时间
②使用redis分布式锁:让一时间只有一个相同请求落到MySql上,反正都是查询同一个信息,之后的其他请求就可以去Redis中找了。
在这里插入图片描述

③使用锁或队列:用加锁或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上,该方法不适用高并发情况。

·

2. 缓存穿透:
在Redis缓存和数据库中都找不到相关的数据。也就是说这是个非法的查询,假设客户端发出了大量非法的查询 比如id是负的 ,每次这个查询都需要去Redis和数据库中查询,可能会导致数据库崩溃
解决缓存穿透的要点,不让非法数据到数据库中查询
解决方案:
①过滤非法查询:在后台服务中过滤非法查询,直接不让他落到Redis服务上。比如id<=0就直接断言。
②缓存空对象:如果他的查询数据是合法的,但是确实Redis和MySql中都没有,那么我们就在Redis中储存一个空对象,这样下次客户端继续查询的时候就能在Redis中返回了。但是,如果客户端一直发送这种恶意查询,就会导致Redis中有很多这种空对象,浪费很多空间
③采用布隆过滤器:它实际上是一个很长的二进制向量 (位图) 和一系列随机映射函数(哈希函数)。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难

·

3. 缓存击穿:
缓存击穿和缓存雪崩类似,也是因为Redis中key过期导致的。只不过缓存击穿是某一个热点的key过期导致的。当有一个热点数据突然过期时,就会导致突然有大量的请求直接落到数据库上,导致数据库崩溃。
解决缓存击穿的要点,不让热点key突然过期
解决方案:
①预先设置热门数据:在 redis 高峰访问之前,把一些热门数据提前存入到 redis 里面,加大这些热门数据 key 的时长。
②实时调整:现场监控哪些数据热门,实时调整 key 的过期时长。
③使用redis分布式锁:让一时间只有一个相同请求落到MySql上,反正都是查询同一个信息,之后的其他请求就可以去Redis中找了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐