面试笔记 — Redis

1.特性

     1) Redis的数据存放在内存中(速度快;减少计算的时间;减轻数据库压力);

          请求处理单线程( 没有创建线程、销毁线程带来的消耗;b. 避免了上线文切换导致的CPU消耗;c. 避免了线程之间带来的竞争问题,例如加锁释放锁死锁等等);

          同步非阻塞 I/O,多路复用处理并发连接.。

     2)相比HashMap/Memcached,其有更丰富的数据类型;支持多种编程语言;功能丰富:持久化机制、内存淘汰策略、事务、发布订阅;支持集群、分布式

     3)单个命令是原子性的(比如get set mget mset),要么成功要么失败,不存在并发干扰的问题

     4)提供一组命令同时执行,提供事务(multi )和监听(watch)---->

           事务可能引发的问题:例如入队的命令语法错误会直接报错不执行。但比如对String 使用Hash的命令,参数个数正确,但数据类型错误等的运行时错误只有错位的命令没有执行,但其他命令没有受到影响

     5)支持Lua脚本: 一次发送多个命令,减少网络开销Redis会将整个脚本作为一个整体执行,不会被其他请求打断,保持原子性对于复杂的组合命令,我们可以放在文件中,可以实现命令复用; 

2. 缓存和数据库不一致

       非高并发下:  双删策略 先删缓存  写数据库 延迟  再删缓存

          高并发下 :  内存队列做 异步串行化

                             删除缓存->更新数据库

                            读缓存发现不存在->将更新缓存请求放入队列,然后等待,同样的读操作

  3.缓存雪崩:缓存挂掉  导致 数据都去请求DB

     发生前:

         存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

         如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。

         设置热点数据永远不过期

    发生中:

          中:本地eccache缓存+hystrix限流 降级

          后:redis持久化,一旦重启自动从磁盘加载数据 快速恢复

 4.缓存穿透

       缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

      解决方案:

      接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
      从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

  5.缓存击穿:

        热点问题缓存过期恰好被大量访问,这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

       1、热点数据永不过期   

       2、加锁 第一个线程若未读到数据就加锁从数据库读取,然后放入。

      3、定时过期前获取

  6.内存回收

     1)立即过期(主动淘汰)   2)惰性过期(被动淘汰)   3)定期过期

  7.淘汰策略

     Redis的内存淘汰策略,是指当内存使用达到最大内存极限时,需要使用淘汰算法来决定清理掉哪些数据,以保证新数据的存入。

      1)策略   (建议使用volatile-Iru,在保证正常服务的情况下,优先删除最近最少使用的key。)

           后缀:   LRU,最近最少使用。     LFU,最不常用,按照使用频率删除,   random,随机删除

           前缀:   volatile是针对设置了ttl的key,allkeys是针对所有

策略

含义

noeviction

默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时 Redis只响应读操作。

volatile-lru

根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够内存为止。如果没有可删除的键对象,回退到noeviction策略。

allkeys-lru

根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够内存为止。

volatile-lfu

在带有过期时间的键中选择最不常用的。

allkeys-lfu

在所有的键中选择最不常用的,不管数据有没有设置超时属性。

volatile-random

在带有过期时间的键中随机选择。

allkeys-random

随机删除所有键,直到腾出足够内存为止。

volatile-ttl

根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。

    如果没有设置ttl或者没有符合前提条件的 key 被淘汰,那么 volatile-Iru、volatile-random、volatile-ttl 相当于 noeviction(不做内存回收)

  6.Redis持久化策略

     https://blog.csdn.net/zhouhuahao/article/details/116058232

 7.高可用

   1)哨兵:

      本质上只是一个运行在特殊模式之下的Redis。Sentinel 通过info命令得到被监听Redis 机器的 master,slave等信息。以够实现主从自动切换和获取主从切换后的最新的master节点, 来保证服务的可用性

   2)Sentinel 集群

       Raf算法: 准备(都是Follower状态)--- > 产生候选节点  ---->   Leader选举  -----> 心跳检测 ---->  日志复制(节点同步)

   3) master选举和从节点产生        

         对于所有的slave节点,一共有四个因素影响选举的结果,分别是断开连接时长、优先级排序、复制数量、进程id。

      Ⅰ、如果与哨兵连接断开的比较久,超过了某个阈值,就直接失去了选举权。

      Ⅱ、如果拥有选举权,那就看谁的优先级高,这个在配置文件里可以设置(replica-priority 100),数值越小优先级越高。

      Ⅲ、如果优先级相同,就看谁从master中复制的数据最多(复制偏移量最大),选最多的那个

      Ⅳ、如果复制数量也相同,就选择进程id最小的那个

      Ⅵ、选出Sentinel Leader之后,由Sentinel Leader向某个节点发送 slaveof no one 命令,让它成为独立节点。然后向其他节点发送slaveof x.x.x.xxxxx(本机IP端口),让它们成为这个节点的从节点,故障转移完成

 4) 10秒一次发送info命令获取最新拓扑结构 只监控主节点即可 ;2秒一次 判断各个节点的哨兵对主节点是否正确一致; 1秒一次 每个哨兵向各个节点 及其他哨兵发送ping 判断心跳

10.Redis-Cluster集群

     其结构特点:
1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2、节点的fail是通过集群中超过半数的节点检测失效时才生效。
3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。

你可能感兴趣的:(面试知识点)