(面试) redis相关问题

1. redis原理

Redis底层核心原理是基于事件的处理流程。主程序处于一个阻塞状态的事件循环中等待事件,当有事件发生时,根据事件的属性分到相应的处理含函数进行处理。事件是以并发的方式发送到服务处理器,服务处理器将事件整合到一个有序队列中,并分发到具体的请求处理器进行处理。

Redis采用I/O多路复用的方式,封装了操作系统底层select/epoll等函数,实现对多个套接字 (socket)的监听,这些套接字就是对应多个不同客户端的连接。最后由对应的处理器将处理的结果返回客户端。  参考https://www.jianshu.com/p/397449cadc9a

2.redis是单线程还是多线程?

Redis 在 4.0 之前明明采用单线程但却依然快的原因:基于内存操作、量身打造的数据结构、I/O 多路复用和非阻塞 I/O、避免了不必要的线程上下文切换。 Redis4.0 开始支持多线程,主要体现在大数据的异步删除上面,例如:unlink key、flushdb async、flushall async 等。而 Redis6.0 的多线程则增加了对 I/O 读写的并发能力,因为数据在用户态和内核态之间穿梭是需要进行拷贝的,而这一步是阻塞的,所以通过多个线程并行操作从而更好的提升 Redis 的性能。

3.持久化

Redis为持久化提供了两种方式:

RDB:redis的数据存储在内从中,不定期的将数据异步同步到磁盘上(半持久化), Redis DataBase 的缩写。

AOF:记录redis的所有写操作到aof(append only file)文件中(全持久化) ,AOF 是Append only file的缩写。

redis中默认使用的是RDB实现数据持久化

RDB持久化数据的优缺点:

优势:

  • 适合大规模数据恢复
  • 对数据完整性和已执行要求不高

劣势:

  • 在一定时间间隔内做一次备份,可能会造成最后一次数据丢失
  • fork时,内存中的数据被克隆一份,大致2倍的数据膨胀需要考虑

AOF持久化数据的优缺点:

优势:

  • 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。
  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。

劣势:

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。

4.redis架构

单机、主从复制、哨兵、集群等

1. 单机版

  • 特点:简单
  • 问题:1、内存容量有限 2、处理能力有限 3、无法高可用。

2.主从复制

  • Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。
  • 特点:
  • 1、master/slave 角色
  • 2、master/slave 数据相同
  • 3、降低 master 读压力在转交从库
  • 问题:
  • 无法保证高可用
  • 没有解决 master 写的压力

3.哨兵

Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。
  • 特点:
  • 1、保证高可用
  • 2、监控各个节点
  • 3、自动故障迁移
  • 缺点:主从模式,切换需要时间丢数据
  • 没有解决 master 写的压力

4. 集群

从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

  • 特点:
  • 1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
  • 2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
  • 3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
  • 4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
  • 5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
  • 缺点:
  • 1、资源隔离性较差,容易出现相互影响的情况。
  • 2、数据通过异步复制,不保证数据的强一致性

总结:如果在读数据方面存在瓶颈,则建议采用哨兵模式;如是在写数据方面存在瓶颈,则那建议采用集群模式。

5.如何防止缓存穿透

  • 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去数据库查询。
  • 一些恶意的请求会故意大量查询不存在的key,就会对数据库造成很大的压力。这就叫做缓存穿透。
  • 解决方案: 将查询结果为空的情况也进行缓存,只是缓存时间设置短一点。示例代码如下:
  • 
    
    //1.redis 查询 商品信息
    Object goodObj = redis.get (goodId);
    if(goodObj!=null){
     return  goodObj;
    }
    
    //2.查询数据库
    GoodDetails goodDetails = goodDetailsMapper.selectById(goodId)
    if( goodDetails!=null){
        //3.写入redis ,存入10分钟
        redis.setex(goodId,goodDetails,60*10)
    }
    else{
       //4.  设置无效请求存储到Redis,并设置较低的过期时间 1分钟
       Random sj = new Random(10)
        redis.setex(goodId,null,60*sj.next())
    
    }
    

6. 如何防止缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

解决方案:

1、设计合理过期时间,错开业务交叉存储,如:在缓存的时候给过期时间加上一个随机值,这样就会大幅度的减少缓存在同一时间过期,判断是否为热门商品,如果是则延长过期时间 ,否则则缩短过期时间 。

2、设计Redis架构时,尽可能做到高可用,当个别节点、部分机器出现问题后,不影响整体。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章