0087 Redis面试高频问题

Redis的数据类型

字符串、集合、有序集合、哈希、列表

Redis的线程模型是怎样的?

Redis内部使用 文件事件处理器(file event handler),该文件处理器是单线程的,因此Redis是单线程模型。它采用多路IO复用机制同时监听多个socket,根据socket上事件来选择对应的事件处理器进行处理。

文件事件处理器的结构包括4个部分:

1、多个socket

2、IO多路复用程序

3、文件事件分派器

4、事件处理器

具体的过程为:IO多路复用程序会监听多个socket,将socket产生的事件放入到队列中排队,文件事件分派器每次从队列中取出一个事件,交给事件处理器处理。

为什么大家都用Redis不用memcached呢?

1、Redis支持的数据类型更加的丰富(5种);memcached只支持字符串类型String

2、Redis可以进行持久化,将内存中的数据保存到内存中,重启时可以再次加载进行使用;而memcached数据只能存储在内存中,断电后数据失效;

3、集群模式:Redis目前支持多种集群模式:主从模式、sentinel模式、cluster模式(最佳);而memcached没有原生的集群模式,需要客户端自己往集群中分片写入数据。

4、Redis是单线程的多路IO复用模型;而memcached是多线程、非阻塞IO复用的网络模型。

举例说明Redis数据类型的使用场景

String

String既可以是字符串。也可以是数字

应用场景——常规计数:微博数、粉丝数、点击数

Hash

hash非常适合存储对象

应用场景:存储用户信息、商品信息

List

list是一个双向链表

应用场景:粉丝列表、好友列表、消息列表;

另外lrange可以实现从某行开始读取多少个元素,可以基于list实现分页查询(如微博下拉不断分页)

Set

集合实现的功能与List相似,区别是它可以排重。可以方便求交集、差集、并集

场景:共同关注好友、共同喜好

Zset

有序集合增加一个权重参数score,使得元素按照score有序排列。

应用场景:直播中实时排行榜——在线用户列表、礼物排行榜、弹幕消息

Redis的过期删除策略?

在set key的时候,可以指定key的过期时间,通常有两种过期删除策略:

1、定期删除:每隔100ms随机抽取一些设置了过期的key,检查其是否过期,若过期则删除。这里随机抽取是为了降低CPU的消耗;

2、惰性删除:定期删除会漏掉一些过期key,只有当你去查询key的时候,才会判断它是否过期做删除处理,这就是惰性删除。

以上两种方式还是无法保证能完全删除过期key,极端情况可能导致内存耗尽,因此还需要Redis的内存淘汰机制

已知MySQL中有3000w条数据,Redis只有30w,如何保证Redis中的数据都是热点数据?

该问题其实就是在问:Redis的内存淘汰策略

Redis提供了以下内存淘汰策略:

1、volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰;

2、volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰;

3、volatile-random:从已设置过期时间的数据集中任意选择任意选择数据淘汰;

4、allkeys-lru:当内存不足以容纳新写入数据时间,在键空间中,移除最近最少使用的key(这个是常用的)

5、allkeys-random:从数据集中任意选择数据淘汰;

6、no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入时,新写入操作会报错。

如何保证Redis挂掉之后重启数据还能恢复?

该问题其实是在问:Redis的持久化机制

  • RDB方式持久化:快照是将内存中的数据状态进行记录,因此快照的数据量比数据本身小很多倍。Redis以快照方式记录某个时刻内存中数据的状态,定时将内存中的数据加载到磁盘,实现持久化。功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数。

img

  • AOF方式持久化:AOF是只记录对Redis的操作命令,通过Redis通信协议(RESP)进行存储,将AOF定时保存到磁盘,在恢复是只需要按照AOF记录的命令执行就能得到和原来一样的数据。

    img

    每当定时执行服务器任务或者函数时,flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作

    AOF写入保存:

    WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件

    SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

    • RDB与AOF对比

      1、RDB快照文件更小,恢复效率更高,是Redis默认方式;AOF的文件会越来越大,需要重写机制保证AOF文件的大小;

      2、AOF的更新频率更高,且AOF更安全。

      3、RDB断电后重启,最近一次快照将丢失,可能丢失最近几分钟的数据;而AOF丢失最近几秒的数据,因此更安全。

什么是一致性哈希?哈希槽呢?

一致性哈希流程

img

  • 服务器节点进行哈希,将其映射到一个0-2^32范围环上;
  • 相同的哈希方法,对key进行哈希,映射到哈希环上;
  • 将数据映射的位置顺时针查找将数据保存到第一个找到的服务器上,如果找了一圈找不到,就放在第一个服务器上。

优点:与传统哈希相比,一致性哈希受节点数据量变动的影响很小新增或删除节点只影响下一个节点

哈希槽:Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数。

Redis 集群没有使用一致性hash, 而是使用哈希槽

哈希槽的优点

当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;

当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;

在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务。

Redis事务

事务命令:Multi(标志接下来的命令需要组合执行)、exec(将以上命令组合执行)、watch命令实现;

原理是将多个命令按顺序加入队列中一次性执行

特点

1、事务命令无法加塞任务;

2、redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,不支持回滚

什么是缓存穿透,解决方法?

查询一个不存在的key:当用户查询某个数据,没有命中Redis缓存,于是向数据库中去查询,还是没找到,费了半天功夫查询失败;当用户请求很多都没有命中缓存,就会去持久层查询,给数据库造成很大的压力,这就是缓存穿透。

缓存穿透的解决方法

1、布隆过滤器:先对请求进行判断,如果请求的结果不在数据库中,将不会执行查询操作;

2、设置空对象:查完一次数据库没找到数据,将一个空对象存入缓存,避免读取数据库;

什么是缓存击穿(热点key),解决方法?

缓存中热点key在某个时间点失效,此时刚好有大量的并发请求过来,在缓存中没命中都去数据库查询,相当于缓存被击穿了,数据库可能被压垮;

缓存击穿的解决方法

使用互斥锁(mutex key),对缓存查询加锁,如果key不存在,就加锁,然后读取数据库,将key放入缓存,解锁;

什么事缓存雪崩,解决方法?

缓存在某个时间点大面积失效,请求落到数据库上,造成数据库崩掉。

缓存雪崩的解决方法

1、在过期时间上加一个随机时间,避免同时失效;或缓存

2、保持缓存层你的高可用:使用Redis 哨兵模式或 Redis Cluster模式,保证请求落在Redis;

3、限流+降级:限制流量,服务降级,保证核心功能可用;

4、互斥锁:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。

Redis与数据库的一致性实现

保证一致性的关键措施:

1、读数据从缓存读,不要从数据库读

2、数据先淘汰缓存,再写入数据库;先更新DB数据,然后通过发送操作缓存的消息到消息队列,进行更新缓存操作,这里还需要的一个操作就是利用消息队列的重试机制,保证缓存能够更新成功,如果多次消费失败,可能是由于网络原因或者redis服务挂了,此处可以添加告警处理。

Redis集群方案

1、主从模式

2、哨兵模式

3、Cluster模式(最优)

本文参考:https://blog.csdn.net/qq_34337272/article/details/80012284

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值