缓存中间件-Redis面试问题总结

Redis为什么快?

Redis的QPS最新官方数据为 10W+的查询次数。

  1、Redis是基于内存的 ,绝大部分的请求是纯粹的内存操作,执行效率高。

  2、数据结构简单,对数据库库的操作也简单,数据复杂度为O(1)。

  3、主线程(IO事件的处理,过期键的处理,集群协调等会被封装成周期性的任务轮询调起)采用单线程设计,所有的读写请求都有一个主线程串行处理,因此不会有并发的问题,避免了上下文切换和锁之间的竞争,单线程也可以处理高并发的请求,多和计算机也可以启动多个实例。

  4、使用IO多路复用模型,非阻塞IO。

Redis常用的数据类型?

  1、String 最基本的数据类型,二进制安全。

  2、Hash String元素组成的字典,适合用于存储字典。

  3、List 列表,按照String的查询顺序排序。

  4、Set String元素组成的无需集合,通过HASH表,不允许重复。

  5、Sorted Set 通过分数对几个中的成员从小到大排序。

  6、用于计数的HyperLogLog,用于支持存储地理位置的Geo。

从海量数据里查询出某一固定前缀的KEY?

  使用Keys指令一次返回所有匹配的Key,键的数据量过大会使服务卡顿,这时候可以使用SCAN指令,需要基于游标迭代器,需要基于上一次的游标延续之前的迭代过程,以0作为新的游标开始作为新的迭代,直到游标返回0完成一次遍历,不保证每次迭代都返回给定数量的元素,一次返回的数量不可控,可以使用count参数约束。

如何通过Redis实现分布式锁:

  SETNX key value 指令,如果key不存在则创建并赋值,不指定过期事件则长期有效,通过给该KEY设置过期事件,来解决锁长期占用的问题。但由于获取锁和设置过期时间单个都是原子性的,二者结合起来就不具有原子性,为了解决分布式锁的原子性问题,新版本的redis把获取锁和设置过期时间合并成一个原子指令来解决分布式锁的长期有效问题。

大量的KEY同时过期要注意什么?

  集中过期,由于清理大量的KEY会很耗时,会出现短暂的卡顿,解决方案是给给个key设置过期时间的时候给每个KEY的过期时间添加随机值。

如何使用Redis做异步队列?

  使用List作为队列,使用RPUSH生产消息,使用LPOP消费消息,但LPOP是不会等到队列有值才会消费,因此有可能空消费,可以在应用层引入Sleep机制调用LPOP重试。也可以使用BLPOP指令做更精准的阻塞控制,这种方式只适用消费者和生产这1:1。

如何适用redis实现一个生产者生产消息,多个消费者消费消息?

  采用Redis的Pub/Sub,及发布/订阅模式,该模式下的缺点是消息是无状态的,不能保证服务是否可达,如果要考虑消息的状态可靠性就要适用专业的消息中间件。

Redis如何做持久化?

  1、RDB(快照持久化),保存某个时间点全量数据快照

    手动触发方式:可以通过SAVE或BGSAVE生成,SAVE指令会阻塞Redis服务主进程的客户端请求,直到创建RDB完成。BGSAVE指令,主进程会Fork一个子进程来创建RDB文件,主进程可以继续处理客户端请求,执行lastsave返回上一次的生成RDB的时间戳。

    自动触发方式:适用redis.conf文件里面的save m n定时触发,用的是BGSAVE;主从同步时,主节点自动触发;执行debug reload的时候;执行shutdown,且没有开启AOF持久化的时候。

  2、AOF(Append Only File)持久化,保存写状态

    记录所有除过查询指令之外的所有变更数据库状态的指令,以Append的形式追加到AOF文件中(增量),AOF持久化默认是关闭的。

    日志重写解决AOF文件不断增大的问题的过程:主进程fork一个子进程,子进程把AOF文件写到一个临时文件(新的AOF文件是对当前redis的数据生成对应命令,并不会以来原有的AOF文件),主进程持续把redis新的变动写道Buff,同时写道旧的AOF文件。子进程完成文件的重写之后会向主进程会发送一个信号,主进程收到信号之后会把内存中的buff写到新的AOF文件中,然后使用新的AOF文件替换掉旧的AOF文件,

RDB和AOF的优缺点总总结:

  RDB优点:全量数据快照,文件小,恢复快。缺点:无法保存最近一次快照之后的增量数据。

  AOF:可读性高,适合保存增量数据,数据不易丢失。缺点:文件体积大,恢复时间长。

RDB-AOF混合持久化方式:

  目前较为推荐的一种redis持久化方式,该方式下是用bgsave做镜像全量持久化,AOF做增量持久化。在redis实例重启时,会先使用bgsave生成的文件重新构建,再使用AOF文件重放近期的操作指令,来实现完整恢复重启之前的状态。

使用pipeline的好处:

  pipeline和linux管道类似,redis基于请求响应模型,单个请求处理需要一一应答,pipeline可以批量执行命令,将多次IO往返的时间缩减为1次。

redis的同步机制:

  全量同步:1 slave发送sync命令到master,2、master调用bgsave生成RDB文件,在此期间master会把所有的写造作写道缓存中,mater完成写EDB文件后将文件发送给slaver,slaver使用新的RDB文件替换掉旧的RDB文件,master将这期间收集到的增量操作发送给slaver进行回放。

  增量同步:1、master收到用户操作指令后判断是否要传递给slaver,2、将该操作记录到AOF文件中,3、将该造作扩散到其他的slaver,4、将缓存中的数据发送给slaver。

redis Sentinel:

  解决主节点宕机后主从切换问题:检查主从服务器是否正常,当某个节点出现问题可以通过api通知OP,同时自动故障迁移,主从切换。

Gossip流言协议:在杂乱无章中寻求一致。

  1、每个节点随机与对方通信,最终所有的节点的状态一致。

  2、种子节点定期向其他节点发送节点列表及需要传播的信息。

  3、不保证信息一定传送给对方节点,但最终会趋于一致。

如何从海量数据里找到所需(redis集群)

  按照某种规则取划分数据,使数据分散存储在不同节点上,redis集群采用一致性HASH算法,对2的32次方取模,将HASH值空间组织成虚拟的圆环,在节点很少的情况下会出现数据倾斜,因此映入虚拟节点解决数据倾斜问题,带来的问题就是要多做一步映射,映射虚拟节点和实际节点。

原文地址:https://www.cnblogs.com/niuyg928/p/15170024.html