Redis 面试题(常见20道)

1.Redis 面试题
1、什么是 Redis?
2、Redis 的数据类型?
3、使用 Redis 有哪些好处?
4、Redis 相比 Memcached 有哪些优势?
5、Memcache 与 Redis 的区别都有哪些?
6、Redis 是单进程单线程的?
7、一个字符串类型的值能存储最大容量是多少?
8、Redis 的持久化机制是什么?各自的优缺点?
9、Redis 常见性能问题和解决方案:
10、redis 过期键的删除策略?
11、Redis 的回收策略(淘汰策略)?
12、为什么 Redis 需要把所有数据放到内存中?
13、Redis 的同步机制了解么?
14、Pipeline 有什么好处,为什么要用 pipeline?
15、是否使用过 Redis 集群,集群的原理是什么?
16、Redis 集群方案什么情况下会导致整个集群不可用?
17、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
18、Jedis 与 Redisson 对比有什么优缺点?
19、Redis 如何设置密码及验证密码?
20、说说 Redis 哈希槽的概念?


1、什么是 Redis?

是由c语言编写,是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。
因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外string的value的最大限制是512M,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。
比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。
另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。 Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

2、Redis 的数据类型

string:普通的 set,get kv缓存
hash:类型 map结构
list:有序列表 ,可以重复可以通过 list 存储一些列表型数据结构,类似粉丝列表,文章评论列表
set:无序集合,自动去重,需要对一些数据快速全局去重,基于 set 玩差集、并集、交集的操作。
sorted set(zset):排序去重的 set,写进去的时候给一个分数,自动根据分数排序:排行榜

数据类型 数据类型存储的值 说 明
string 可以是保存字符串、整数和浮点数 可以对字符串进行操作,比如增加字符或者求子串:如果是整数或者浮点数,可以实现计算,比如自增等
list 它是一个链表,它的每一个节点都包含一个字符串 Redis 支持从链表的两端插入或者弹出节点,或者通过偏移对它进行裁剪;还可以读取一个或者多个节点,根据条件删除或者查找节点等
set 它是一个收集器,但是是无序的,在它里而每一个元素都是一个字符串,而且是独一无二,各不相同的 可以新增、读取、删除单个元素:检测一个元素是否在集合中;计算它和其他集合的交集、并集和差集等;随机从集合中读取元素
hash 它类似于 Java 语言中的 Map,是一个键值对应的无序列表 可以増、删、査、改单个键值对,也可以获取所有的键值对
zset 它是一个有序的集合,可以包含字符 串、整数、浮点数、分值(score),元素 的排序是依据分值的大小来决定的 可以增、删、査、改元素,根据分值的范围或者成员 來获取对应的元索
hyperloglog(基数) 它的作用是计算重复的值,以确定存储的数量 只提供基数的运算,不提供返回的功能

3、使用 Redis 有哪些好处?

1、数据存储在内存中,读写速度快;
2、支持的数据类型资源丰富;
3、支持事务,操作都是原子性操作;
4、可以设置数据存活的生命周期

4、Redis 相比 Memcached 有哪些优势?

(1)memcached所有的值都是简单的字符串,redis作为其代替者,支持更为丰富的数据类型。
(2)redis的速度比memcached快很多。
(3)redis可以持久化其数据。

5、Memcache 与 Redis 的区别都有哪些?

Redis 支持服务器端的数据操作:Redis比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络 IO 的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能支持更复杂的结构和操作,那么Redis会是不错的选择
集群模式:memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据,但是 Redis 目前是原生支持 cluster模式的

6、Redis 是单进程单线程的?

是单进程单线程的,优点:
一秒钟可以处理几万个请求
非阻塞 I/O 多路复用机制(不处理事件,只轮询请求压入队列)
纯内存操作(操作只有几微秒)
单线程反而 避免了多线程频繁上下文切换的问题

7、一个字符串类型的值能存储最大容量是多少?

Strings类型:一个String类型的value最大可以存储512M
Lists类型:list的元素个数最多为2^32-1个,也就是4294967295个。
Sets类型:元素个数最多为2^32-1个,也就是4294967295个。
Hashes类型:键值对个数最多为2^32-1个,也就是4294967295个。
Sorted sets类型:跟Sets类型相似。

8、Redis 的持久化机制是什么?各自的优缺点?

Redis 提供两种持久化机制 RDB 和 AOF 机制:
RDB(Redis DataBase)持久化方式:
是指用数据集快照的方式半持久化模式) 记录 redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件。持久化 结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
优点:
1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能)
4.相对于数据集大时,比 AOF 的启动效率更高。
缺点:
1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生 故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)

AOF(Append-only file)持久化方式:是指所有的命令行记录以 redis 命令请 求协议的格式完全持久化存储)保存为 aof 文件。
优点:
1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。
2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))
缺点:
1、AOF 文件比 RDB 文件大,且恢复速度慢。
2、数据集大的时候,比 rdb 启动效率低

9、Redis 常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件;(Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照;AOF文件过大会影响Master重启的恢复速度)
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…;这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

10、redis 过期键的删除策略?

redis对这批key是定期删除+惰性删除
定期删除:redis 默认每隔 100ms随机抽取一些设置了过期时间的 key,检查其是否过期了,如果过期就删除。注意:redis是每隔100ms随机抽取一些 key来检查和删除,而不是遍历所有的设置过期时间的key(否则CPU 负载会很高,消耗在检查过期 key 上)。
惰性删除:获取某个key的时候, redis 会检查一下,这个key如果设置了过期时间那么是否过期,如果过期了则删除。如果定期删除漏掉了许多过期key,然后你也没及时去查,也没走惰性删除,如果大量过期的key堆积在内存里,导致 redis 内存块耗尽,则走内存淘汰机制。

11、Redis 的回收策略(淘汰策略)?

noeviction:当内存不足以容纳新写入数据时,新写入操作直接报错(没人用)
allkeys-lru: 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(最常用)
allkeys-random: 当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,(没人用)
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(不合适)
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除(不合适)
LRU 算法:简

12、为什么 Redis 需要把所有数据放到内存中?

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以Redis具有快速和数据持久化的特性。如果不将数据放到内存中,磁盘的I/O速度会严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后将不能继续插入新值。

13、Redis 的同步机制了解么?

参考网址:https://www.jianshu.com/p/41254dc5cb38
全量复制:
1.slave第一次启动时,连接Master,发送PSYNC命令,格式为psync {runId} {offset}
{runId} 为master的运行id;
{offset}为slave自己的复制偏移量由于此时是slave第一次连接master,
slave不知道master的runId,也不知道自己偏移量,这时候会传一个问号和-1,
告诉master节点是第一次同步。格式为psync ? -1

2.当master接收到psync ? -1时,就知道slave是要全量复制,就会将自己的runId和offset告知slave,回复命令+fullresync {runId} {offset}。同时,master会执行bgsave命令来生成RDB文件,并使用缓冲区记录此后的所有写命令
slave接受到master的回复命令后,会保存master的runId和offset
slave此时处于同步状态,如果此时收到请求,当配置参数slave-server-stale-data yes时,
会响应当前请求,no则返回错误。

3.master bgsave执行完毕,向Slave发送RDB文件,同时继续缓冲此期间的写命令。RDB文件发送完毕后,开始向Slave发送存储在缓冲区的写命令
4.slave收到RDB文件,丢弃所有旧数据,开始载入RDB文件;并执行Master发来的所有的存储在缓冲区里的写命令。
5.此后 master 每执行一个写命令,就向Slave发送相同的写命令。
增量复制
1.如果出现网络闪断或者命令丢失等异常情况时,当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行ID。因此会把它们当作psync参数发送给主节点,要求进行部分复制操作,格式为psync {runId} {offset}
2.主节点接到psync命令后首先核对参数runId是否与自身一致,如果一致,说明之前复制的是当前主节点;之后根据参数offset在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送+CONTINUE响应,表示可以进行部分复制;否则进行全量复制。
3.主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态

14、Pipeline 有什么好处,为什么要用 pipeline?

Pipeline:意思是:管道
参链:https://www.codercto.com/a/46408.html
优点:
1.pipeline 通过打包命令,一次性执行,可以节省 连接->发送命令->返回结果 所产生的往返时间,
2.减少的I/O的调用次数。
缺点:
1.pipeline 每批(10k/批)打包的命令不能过多,因为 pipeline 方式打包命令再发送,那么 redis 必须在处理完所有命令前先缓存起所有命令的处理结果。这样就有一个内存的消耗。
2.pipeline 是责任链模式,这个模式的缺点是,每次它对于一个输入都必须从链头开始遍历(参考Http Server处理请求就能明白),这确实存在一定的性能损耗。
3.pipeline 不保证原子性,如果要求原子性的,不推荐使用 pipeline

15、是否使用过 Redis 集群,集群的原理是什么?

其实就是分库分表,去中心化
1、集群是如何判断是否有某个节点挂掉
  首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。

2、集群进入fail状态的必要条件
A、某个主节点和所有从节点全部挂掉,我们集群就进入faill状态。
B、如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.
C、如果集群任意master挂掉,且当前master没有slave.集群进入fail状态

3.redis集群去中心化(所有Master节点并发处理读写)
集群中原则每个Master节点都有一个或多个Slave节点。集群中所有的Master节点都可以进行读写数据,不分主次,记redis集群式去中心化的。每个Master节点与Slave节点间通过Goossip协议内部通信,异步复制。不用我们瞎操心(所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.),但是异步赋值会导致某些特定情况下的数据丢失,即,redis集群不能保证数据的强一致性

4.redis集群的分区规则:虚拟槽分区(槽:slot)
RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据
哈希函数: Hash()=CRC16[key]&16383 按位与
redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储

  1. redisCluster的缺陷(虚拟槽分区的缺点)
    a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了
    b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务
    c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
    d,不支持多数据库,只有0,select 0
    e,复制结构只支持单层结构,不支持树型结构。

6.客户端与redis集群交互方式
由于Cluster架构中无Proxy层,客户端是直接与集群中的任意可用节点直接交互的,【话是这么说,但是一个请求是怎么找到集群中的一个节点的呢,redis有多种策略,一般使用CRC16去hash(key)计算改请求要分配到具体的哪一个节点上。然后才是 客户端与节点的直接操作】对象保存到Redis之前先经过CRC16哈希到一个指定的Node上,

16、Redis 集群方案什么情况下会导致整个集群不可用?

有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用。

17、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?

jedis、redisson、lettuce,官方推荐使用Redisson。
概述:
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;
Jedis中的方法调用是比较底层的暴露的Redis的API,也即Jedis中的Java方法基本和Redis的API保持着一致,了解Redis的API,也就能熟练的使用Jedis。
Redisson实现了分布式和可扩展的Java数据结构,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列。和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
Redisson中的方法则是进行比较高的抽象,每个方法调用可能进行了一个或多个Redis方法调用。
Lettuce:高级Redis客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。目前springboot默认使用的客户端。
伸缩性:
Jedis:使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。
Jedis仅支持基本的数据类型如:String、Hash、List、Set、Sorted Set。
Redisson:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作。
Redisson不仅提供了一系列的分布式Java常用对象,基本可以与Java的基本数据结构通用,还提供了许多分布式服务,其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)。
Lettuce:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作。

18、Jedis 与 Redisson 对比有什么优缺点?

https://my.oschina.net/xiaominmin/blog/1595525
Jedis:
轻量,简洁,便于集成和改造
支持连接池
支持pipelining、事务、LUA Scripting、Redis Sentinel、Redis Cluster
不支持读写分离,需要自己实现
文档差(真的很差,几乎没有……)
Redisson:
基于Netty实现,采用非阻塞IO,性能高
支持异步请求
支持连接池
支持pipelining、LUA Scripting、Redis Sentinel、Redis Cluster
不支持事务,官方建议以LUA Scripting代替事务
支持在Redis Cluster架构下使用pipelining
支持读写分离,支持读负载均衡,在主从复制和Redis Cluster架构下都可以使用
内建Tomcat Session Manager,为Tomcat 6/7/8提供了会话共享功能
可以与Spring Session集成,实现基于Redis的会话共享
文档较丰富,有中文文档

20、说说 Redis 哈希槽的概念?

Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384=16*1024个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

参链:https://www.jianshu.com/p/36a646cef11a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Redis常见面试题包括但不限于以下几个方面: 1. Redis的特点和优势:Redis是一个基于内存的NoSQL数据库,支持多种数据结构和丰富的操作,具有高性能、高并发、持久化、主从同步等特点。 2. Redis的数据结构:Redis支持多种数据结构,包括字符串(string)、列表(list)、集合(set)、有序集合(sorted set)和哈希(hash),每种数据结构都有相应的操作方法。 3. Redis的持久化方式:Redis有两种持久化方式,分别是RDB(Redis Database)和AOF(Append Only File)。RDB是将内存中的数据定期保存到磁盘上,而AOF是将每个写操作追加到文件末尾。 4. Redis的使用场景:Redis可以用于缓存、会话管理、计数器、排行榜、消息队列等多种场景。它的高性能和丰富的数据结构使得它在处理大量并发请求和快速读写的场景下表现出色。 5. Redis的并发访问:Redis采用单进程单线程模式,通过队列模式将并发访问变为串行访问。在Jedis客户端对Redis进行并发访问时可能会出现连接超时、数据转换错误、阻塞等问题,需要注意处理这些并发访问的情况。 综上所述,Redis是一个功能强大的基于内存的NoSQL数据库,具有多种数据结构和丰富的操作方法,适用于多种场景。在面试中,了解Redis的特点、数据结构、持久化方式、使用场景和并发访问等方面的知识是非常重要的。 #### 引用[.reference_title] - *1* *2* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [精选 21 Redis 最常问面试题!收藏一波 !](https://blog.csdn.net/w915209092/article/details/126035419)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值