Redis知识点

1.reids到底是单线程还是多线程

1.redis 在6.0之前的单线程是指网络请求I/O和键值对的读写(命令)是由一个单线程完成的,而其他的持久化 ,集群数据等在6.0之前其实也是有额外的线程来完成的
2.redis在6.0之后引入的多线程是指其网络I/O使用了多线程,而其命令的操作还是由单线程来完成的,所以redis的并发是安全的

2.redis单线程为什么还这么快

1.redis的命令是基于内存操作的,一条命令在内存操作时间是几十纳秒
2.命令运行时单线程的,没有线程切换的开销
3.基于I/O多路复用机制来提升redis的I/O利用率
4.高效的存储结构:全局hash表(一维的数组+二维的链表来组成,redis会根根据set的key值,进行hash运算得到一个常量值,最后会落到一维数组的某个值,然后将key-value按照链表存储到这个区域)以及多种高效的数据结构,比如:跳表,压缩列表,链表等

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

将有序链表改造为类似于"折半查找"算法,可以快速的进行增,删,改,查

4.redis的key过期了,为什么内存没有释放

1.比如 set name mary ex 10 设置name值10秒过期,如果直接修改set name jack,这个时候就会是变成这个值永不过期,修改值时需要注意当前key是否存在过期时间
2.redis对于过期key有两种处理策略,一种是惰性删除,一种是定时删除
 惰性删除:当读/写一个已经过期的key时,redis会触发惰性删除,会去判断这个key是否已经过期,如果已经过期,就会删除这个key
 定时删除:由于惰性删除无法保证过期key及时删除,redis会定期(默认100ms)检测一次,淘汰一批过期的key,这里的一批只是部分key,所以有可能出现key过期了,但是内存并没有释放掉

5.key没设置过期时间为什么被redis主动删除了

假如说我们部署redis服务器的内存是8个g,超过4个g的时候,设置redis内存超过maxmemory限定时,触发了主动清理策略
主动清理策略在redis4.0之前只有6种,4.0之后,又加了两种,一共是8种
a.针对设置了过期时间的key做处理 {
  1.  wolatile-ttl:在删选时会根据过期时间的key,进行先后删除,越早过期越先被删除
  2.volatile-random:就像他的名字一样,在被设置了过期时间的key中,随机进行删除
  3.  volatile-lru( Least Recently Used 最近最少算法):在设置了过期时间的key中会使用LRU算法将“最近最少”使用的数据删掉,redis对key进行采样后,在采样结果中进行数据清理
  4.volatile-lfu(Least Frequently Used - 最不常使用算法):通过key的访问频率,访问时间来淘汰数据
}
b.针对所有的key做处理{
  5.allkeys-random:从所有的key中随机选择并且进行删除
  6.allkeys-lru:  在所有的key中会使用LRU算法将“最近最少”使用的数据删掉,redis对key进行采样后,在采样结果中进行数据清理
 7.allkeys-lfu: 在所有的key中,通过key的访问频率,访问时间来淘汰数据
}
c.不处理{
   8. noeviction:不会删除任何的数据,拒绝所有写入操作,并返回客户端错误信息,此时redis只响应读操作
}

6.LRU和LFU的区别

LRU:(Least Recently Used 最近最少使用):淘汰很久没有被访问过的数据,根据最后一次访问时间来进行判断
LFU(Least Frequently Used 最不经常使用):淘汰一批最近使用次数最低的数据,以次数作为参考,如果使用大量热点数据,可以考虑使用LFU,比如A五分钟前访问了500次,现在没有访问,B现在访问了1次,如果使用LRU算法,就会把A淘汰掉,不符合实际需求,所有推荐使用LFU

7.删除key的命令会阻塞redis吗

1.删除单个的字符类型的key,时间复杂度为O(1)
2.删除单个列表,集合,有序集合,哈希表类型的key,如果这个key对应很多值的话,需要在redis进行遍历才能删除,时间复杂度为O(N),N为数据结构内部的元素数量
3.如果一个单字符类型,很大,例如几百M的话,也会很占用内存,也会阻塞redis

8.Redis集群数据Hash分片算法

redis clasuster (集群)将刷剧划分为16384个slots(槽位),槽位的信息存储在每个集群节点中
挡redis cluster的客户端连接集群是,他会得到一份集群的槽位配置信息,并将其保存在客户端本地,当客户端发送来请求的查找某个key,可以根据槽位定位算法找到目标节点

槽位定位算法:
cluster 会对key使用crc16的算法得到一个整数值,然后对这个整数值进行16383取模来找到具体的槽位

9.redis执行命令竟然有死循环阻塞BUG

使用randomkey来随机取出一个key值,有可能导致redis死循环阻塞

当redis去取出key的时候,如果这个key过期会再次去查到一个key,如果这个时候redis存在大量过期key的话,就会一直去查找

主要发生在主从下,去从服务器查找数据,因为如果这个key过期,需要主服务器生成一条删除命令同步到从服务器,从服务器才能删除这个key,这个时候就会导致,redis一直重复去数据,死循环

这个bug在5.0以后redis进行修改,在查找数据的时候,默认如果在一定的次数内(好像是100次),如果找不到数据,就会退出循环

 10.redis主从切换导致了缓存雪崩场景

导致这种原因的情况主要是服务器之间的时间不一致:

假设主服务器时间为12点,从服务器时间为1点,这个时候如果主服务器发生宕机,从服务器升为主服务器,就会清理掉这些本身不属于过期的key,导致大量key过期,发生雪崩

所以保证主从之间的时间一致性,避免这种问题发生

11.redis主节点宕机导致数据全部丢失场景

使用主从+哨兵模式进行部署
为了提升性能,master没有开启持久化功能
进程使用supervisor进行监控,配置redis宕机,自动重启

此时如果redsi宕机,会出现以下几种情况:
master宕机,哨兵还未进行主从切换,进程被supervisor拉起了

但是master没有做持久化,重新拉起后,是一个空实例

这个时候slave为了保证与master同步会清空实例的数据,slave也成了一个空实例

主从的数据全部丢失了

这种情况下,保证数据的同步,如果配置了哨兵这些配置,尽量不需要使用supervisor这些工具

 12.redis线上数据如何进行备份

可以写crontab定时任务,每个13.时间定时保存rdb或者aof文件到另一台机器当中

13.redis主从复制风暴是怎么回事

当一台主节点下方有多个从节点时,从节点每次重启会发送命令到主节点,主节点会把内存生成rdb文件发送到各个从节点,如果从节点过多,redis主节点压力就会非常的大,这就是所谓的主从复制风暴

可以采用“薪火相传”模式,可以从节点下方挂从节点,不要所有的从节点都挂到一台主节点下方

14.redis集群网络抖动导致频繁切换主从怎么处理

集群中的每个主从配置之间是可以相互通讯的,当一个主从因为网络原因长时间得不到回复的话,其他主从节点会认为这个节点挂了,从而这个主从会从新选取新的主节点,导致了频繁的切换主从

解决这个问题可以使用redis集群的 cluster-node-timeout 配置,当某个节点持续超时超过timeout时间,才可以认为该节点发生了故障进行主从切换

15. redis集群支持批量操作命令吗

如果直接操作mset,mget这样的原生批量操作命令,redis集群只支持所有的key在同一slot(插槽)上的情况,如果一定要批量操作可以在key前面加{xxx},这样数据会根据参数分片算法计算括号内的值,这样才可以确保可以可以落到不同的slot当中

mset {user}:1:name jack {user}:1:age 18

16.lua脚本可以在集群当中运行吗

lua脚本在集群当中运行,脚本里面操作redis的所有key必须在同一节点上,这种的话我们可以给lua脚本里面的key值前面都加上hash tag 也就是{xxx},这样就可以保证脚本内的key都在同一个节点上

 

posted @ 2022-07-11 12:27  -韩  阅读(159)  评论(0编辑  收藏  举报