Redis 2023面试5题(一)

一、Redis是单线程还是多线程

在面试中,当被问到Redis是单线程还是多线程这个问题时,可以按照以下思路进行回答:

  1. 首先,Redis的核心业务部分是单线程的,即命令处理部分是单线程的。
  2. 然而,Redis也支持多路复用技术,例如使用多线程来处理多个客户端请求,以便提高并发性能。
  3. 在Redis的版本迭代过程中,引入了多线程异步处理一些耗时较旧的任务,例如异步删除命令unlink,以及在核心网络模型中引入多线程,进一步提高对于多核CPU的利用率。
  4. 总的来说,Redis在核心业务部分是单线程的,但是在辅助任务和处理多个客户端请求时使用了多线程。这主要是为了提高Redis的性能和可伸缩性。

补充说明:

  • Redis 6.0版本之前的单线程指的是其网络I/O和键值对读写是由一个线程完成的,
  • Redis6.0引入的多线程指的是网络请求过程采用了多线程,而键值对读写命令仍然是单线程处理的,所以Redis依然是并发安全的
  • 也就是只有网络请求模块和数据操作模块是单线程的,而其它的持久化、集群数据同步等,其实是由额外的线程执行的

二、Redis6.0与之前版本有什么不同

Redis6.0相较于之前的版本主要有以下改进:

  1. 支持模块系统:Redis6.0引入了模块系统,可以动态加载模块,使得Redis可以支持更多的数据类型和功能。
  2. 支持Lua脚本:Redis6.0引入了Lua脚本语言,可以用于实现更复杂的业务逻辑。
  3. 支持自动分区:Redis6.0引入了自动分区功能,可以将数据自动分布在多个Redis实例之间,提高可伸缩性和可靠性。
  4. 支持集群:Redis6.0引入了集群功能,可以支持分布式存储和负载均衡,提高Redis的并发性能和可靠性。
  5. 支持SSL连接:Redis6.0支持SSL连接,可以提供更加安全的数据传输保障。
  6. 优化性能:Redis6.0对性能进行了优化,可以提高Redis的读写效率和稳定性。
  7. 改进RDB和AOF格式:Redis6.0对RDB和AOF格式进行了改进,可以提高数据恢复的速度和完整性。

总之,Redis6.0相较于之前的版本在功能、性能、安全性和可伸缩性等方面都有所改进和提升。

三、Redis单线程为什么还这么快

Redis之所以能够以单线程的方式运行得如此快速,主要有以下几个原因:

  1. 纯内存操作:Redis的所有数据都存储在内存中,避免了硬盘读写和网络传输等耗时的操作,因此能够快速地处理请求。
  2. 高效的数据结构:Redis的数据结构是专门设计的,例如Hash和Set等数据结构都是在内存中以数组的方式存储,使得查找和操作都非常高效。
  3. 单线程优势:由于Redis是单线程的,因此不需要进行线程切换和锁竞争等操作,避免了这些耗时的操作对性能的影响。
  4. 非阻塞IO模型:Redis使用了非阻塞IO模型,使得其在处理客户端请求时不会阻塞其他操作的执行,从而提高了Redis的并发性能。

综上所述,Redis能够以单线程的方式运行得如此快速,主要是因为其纯内存操作、高效的数据结构、单线程优势和非阻塞IO模型等因素的综合作用。

四、Redis底层是如何使用跳表来存储的

Redis的底层使用跳表(SkipList)来存储数据,跳表是一种基于链表的数据结构,可以在链表的基础上增加多级索引,从而提高查询效率。Redis的跳表实现包括ZSET和ZORDERBYLENGHT命令。

具体来说,Redis的跳表实现包括以下几个部分:

  1. 链表:Redis的链表是一个双向链表,每个节点包含一个有序的元素和一个指向下一个节点的指针。
  2. 字典:Redis的字典是一个哈希表,用于存储跳表节点的索引。每个哈希表节点包含一个键值对,其中键是元素的值,值是跳表节点的指针。
  3. 跳表:Redis的跳表是一个多级结构,每一级都包含一个链表和一个字典。每个节点在每一级中都有一个指针,指向该节点的下一个节点。

当进行插入或删除操作时,Redis会根据元素的值计算出该元素在跳表中的位置,然后将元素插入到相应的级别中。在进行查询操作时,Redis会从最高级的链表开始向下遍历,直到找到第一个大于等于查询元素的节点为止。

需要注意的是,Redis的跳表实现并不是严格按照SkipList的标准算法实现的,而是在SkipList的基础上进行了一些优化和调整,例如使用双向链表代替了单向链表,使用哈希表代替了每个节点都有的游标等。

如图:
Redis 2023面试5题(一)_第1张图片
查找32时:

  • 首先从1开始找,大于 1 ,
  • 向右找到25,大于 25,
  • 向右找到100,小于100,
  • 返回25向下找,大于 25,小于50,
  • 继续向下找,大于25
  • 向右找到32

五、Redis的key过期了,为什么内存没有释放

  1. 有可能原来的key设置了过期时间,但修改key值后没有带上过期时间,导致key永远不过期
127.0.0.1:6379> SET  name tom EX 1000 
OK
127.0.0.1:6379> SET name jack 
OK
127.0.0.1:6379> ttl name
(integer) -1
127.0.0.1:6379> 
  1. Redis的key过期了,内存并没有立即被释放,这可能是因为Redis正在执行一些未完成的写入或读取操作。
  2. Redis 的 key 过期后,其对应的内存空间并不会立即被释放。可能是因为 Redis 使用了一种叫做“惰性删除”的策略来管理内存空间。
    具体来说,当一个 key 过期后,Redis 并不会立即将其从内存中删除。相反,它会将该 key 标记为“过期”,并在下一次垃圾回收时将其删除。这样可以避免频繁地进行内存回收操作,从而提高性能。

在实际使用中,如果需要立即释放过期的键,可以使用Redis提供的主动淘汰策略,例如volatile-ttl(默认值)和allkeys-lru等。这些策略会定期扫描内存中的键,并根据一定的规则将过期的键从内存中淘汰,从而释放内存空间

你可能感兴趣的:(#,redis,Java,2023面试大全,redis,面试,java)