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做处理
- 根据过期时间先后删除(volatile-ttl)
- 随机删除(volatile-random)
- 使用LRU算法删除(volatile-lru)
- 使用LFU算法删除(volatile-lfu)
- 针对所有的key做处理
- 随机删除(allkeys-random)
- LRU(allkeys-lru)
- LFU(allkeys-lfu)
- 不处理
- 不会删除任何数据,拒绝所有写入操作并返回给客户端错误信息“(error)OOM command not allowed when used memory ",此时,服务只响应读操作(noeviction)
LRU:最近最少使用淘汰算法
LFU:最近一段时间访问次数最少淘汰算法
redis删除元素的时间复杂度
O(N)N为被删除的key的数量
删除单个字符串类型的key,时间复杂度为O(1)
删除单个列表,集合,有序集合或者哈希表类型额key,时间复杂度为O(M),M为以上数据结构内的元素数量。