Redis面试必问
-
Redis到底是单线程还是多线程的
Redis6.0之前的单线程指的是其网络I/O和键值对读写是有一个线程完成的
Redis6.0引入的多线程指的是网络请求过程采用了多线程,而键值对读写命令仍然是单线程处理的,所以Redis依然是并发安全的
也就是只有网络请求和数据操作模块是单线程的,而其他的持久化、集群数据同步等,其实是由额外的线程执行的
-
Redis单线程为什么还能这么快?
- 执行命令基于内存操作,一条命令在内存里操作的时间是几十纳秒
- 命令执行是单线程操作,没有线程切换开销
- 基于I/O多路复用机制提高Redis的I/O利用率
- 高效的数据存储结构:全局hash表以及多种高效数据结构,比如:调表、压缩列表、链表等
-
Redis 底层数据是如何使用跳表来存储的?
跳表:将有序链表改造成支持近似“折半查找”算法,可以进行快速的插入、删除、查找操作
-
Redis key 过期了为什么内存没有释放?
在使用Redis时,肯定经常使用SET命令
SET除了可以设置key-value之外,还可以设置key的过期时间,像下面这样:
127.0.0.1:6379> SET name zhangsan EX 120 OK 127.0.0.1:6379> TTL name (integer)117
此时如果修改key的值,但只是单纯的使用SET命令,而没有加上过期时间的参数,那这个key的过期时间将会被擦除
127.0.0.1:6379> SET name lisi OK 127.0.0.1:6379> TTL name (integer)-1
导致这个问题的原因在于:SET命令如果不设置过期时间,那么Redis会自动擦除这个key的过期时间
如果有大量不过期的key,消耗过多的内存资源,所以在SET命令的时候,注意点,避免过期时间丢失的问题
Redis对于过期的key一般有惰性删除和定性删除两种策略:
- 惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,判断key是否过期,如果过期会直接删除这个key
- 定时删除:由于惰性删除无法保证冷数据被及时删除,所以Redis会定期(默认100ms)主动淘汰一批已经过期的key,这里的一批只是部分过期的key,所以可能会出现部分key已经过期还没有被清理的情况,导致内存并没有释放