Redis常见问题(1)

61 阅读2分钟

redis是单线程还是多线程?

redis6.0之前的单线程指的是其网络I/O和键值对读写是由一个线程完成的。

redis6.0引入的多线程指的是网络请求过程中采用了多线程,而键值对读写命令仍然是单线程处理的,所以redis是并发安全的。

也就是只有数据操作模块是单线程的,而其他的持久化,集群数据同步,其实是由额外的线程执行的。

redis单线程为什么还这么快?

命令基于内存操作,一条命令在内存里操作的时间是几十纳秒

命令执行基于单线程,没有线程切换开销

基于I/O多路复用机制提升redis的I/O利用率

高效的数据存储结构:全局hash表以及多种高效的数据结构,比如:跳表,压缩列表,链表等。

redis底层数据是如何用跳表来存储的

基于有序链表建立起跳表,跳表可以更快的进行元素查找,本质上是用空间换时间。

keys过期了为什么内存没释放

原因可能如下

set k1 v1 EX 120 #设置过期时间
#在过期时间内重新设置key的值,但不带过期时间,key将不会有过期时间
set k1 v11

redis对于过期key的处理一般有惰性删除和定时删除两种策略

惰性删除:当读写一个已经过期的key,会触发惰性删除,如果key已经过期了,则直接删除

定时删除:由于惰性删除无法保证冷数据及时删除,所以redis会定期主动删除一批已经过期的key。

key没设置过期时间为什么被删除了

当redis已用内存超过maxmemory限定时,触发主动清理策略。

有8种清理策略

  • 针对设置了过期时间的key做处理
  1. 根据过期时间先后删除(volatile-ttl)
  2. 随机删除(volatile-random)
  3. 使用LRU算法删除(volatile-lru)
  4. 使用LFU算法删除(volatile-lfu)
  • 针对所有的key做处理
  1. 随机删除(allkeys-random)
  2. LRU(allkeys-lru)
  3. LFU(allkeys-lfu)
  • 不处理
  1. 不会删除任何数据,拒绝所有写入操作并返回给客户端错误信息“(error)OOM command not allowed when used memory ",此时,服务只响应读操作(noeviction)

LRU:最近最少使用淘汰算法

LFU:最近一段时间访问次数最少淘汰算法

redis删除元素的时间复杂度

O(N)N为被删除的key的数量

删除单个字符串类型的key,时间复杂度为O(1)

删除单个列表,集合,有序集合或者哈希表类型额key,时间复杂度为O(M),M为以上数据结构内的元素数量。