1. Redis的持久化策略有哪些?有什么区别?项目中一般用哪一种?

1) RDB和AOF
2) RDB原理是对整个当前内存数据进行快照备份,体积小;AOF原理是每条操作指令都会持久化到文件,导致文件体积比较大.RDB的两次备份时间(默认时间)间隔最短1min,时间长,容易导致数据丢失;而AOF默认间隔时间是1s,时间短,数据完整性高!恢复速度上来说,RDB要比AOF速度快些,因为体积小.
RDB:内存数据,体积小,1min,备份时间长,数据容易丢失; AOF:每条操作指令,体积大,1s,数据完整性好;
RDB要比AOF快,因为体积小;

3) 实际项目我们公司有运维团队维护Redis服务器的配置,我没有权限进行修改,但是我了解到通常为了保证数据的完整更高,同时开启RDB和AOF,Redis在启动时也会优先加载完整性更高的AOF,这是RDB备份更多的为了在AOF文件损坏的情况下使用.

2.如果系统中存入Redis的数据过多,导致Redis压力过大,怎么解决?

可以搭建Redis主从架构+哨兵集群

3.请说说Redis主从架构中,主从之间怎么保证数据一致的?

首先,Redis的主和从之间会有全量同步和增量同步
通常,Redis在第一次从节点连接主节点时,会进行一次全量同步,在之后,主节点接受到新数据时,会和从节点做增量同步
大概说说全量同步过程,分成两个阶段,第一阶段,从节点请求主节点同步版本,第二阶段,主节点执行bgsave进行RDB备份,然后把RDB备份发送给从节点,从节点清空本地数据,还原RDB文件.
大概说说增量同步过程在主节点使用xxx_backlog文件存储了所有写入请求的执行,定期同步给从节点,为了保证同步的数据量最小,xxx_backlog设置offset偏移量记录上次同步的位置,以便下次同步从offset开始.但是,如果某次增量同步的数据量超过backLog文件的大小,就会触发1次全量同步.
注意:Redis的主从架构必须开启RDB

4.如果Redis主从架构中,主节点崩了怎么解决?Redis的哨兵如果崩了怎么办?

如果主节点崩了,会由哨兵通过投票选举一个新的主节点出来;
搭建哨兵模式,一般都是哨兵集群,通常哨兵节点数量为3台起步.为了选举机制,如果3台机器超过2票才可以通过投票
Redis的哨兵是怎么选举的?(问法:Redis的哨兵是如果进行故障恢复的?)

  1. 1.哨兵集群中的所有哨兵会投票确认master阶段是否真正宕机,需票数过半
  2. 2.接着哨兵集群中选举一个哨兵作为leader,该leader负责整个主从恢复的工作
  3. 3.哨兵集群选举出一个slave节点作为新的mater
  4. 4.哨兵leader试试主从切换,新的master同时其余的slave节点进行数据同步
  5. 5.哨兵leader通知客户端主从状态的变化
  6. 6.最后,哨兵leader会等待之前宕机的master复活,然后让复活的节点成为slave节点,而不是master节点.

6.什么是Redis缓存穿透?如何解决?(必问)

缓存穿透是指恶意用户在短时间发出海量的请求访问数据库和缓存都不存在的数据时,可能引发的数据库奔溃行为
解决办法:
1) 设置key – null + 30秒过期时间,这样能应付同一个key的穿透情况
(也就是让系统返回一个空对象给用户)
第一次访问某个key时没如果缓存和数据库都不存在,则把该key存入redis,value为null,这样后续访问该key就走redis缓存.
防止过多无效key占用Redis内存,必须设置过期时间(如30秒)
2) 布隆过滤器(BloomFilter)
先将需要缓存的所有key,放入布隆过滤器,当一个查询请求过来时,现金过布隆过滤器查询,如果判断该key存在,则继续查询(访问缓存或数据库);如果判断该key不存在,则直接丢弃.我大概了解布隆过滤器的原理是这样,先将所有key利用特定算法存储到一个二进制变量中,当请求某个key时,利用n个哈希函数计算得到该key的n个位置值,一但位置值包含0,代表该key必须不存在.如果所有位置值为1,代表该key大概率存在(布隆过滤器有一定的误判率)
简单说说,布隆过滤器相当于在查询缓存之前先在集合中查询key是否存在,如果不存在就直接返回
3)使用Sentinel限流
给会涉及到高并发的查询逻辑设置一个熔断器,当出现缓存和数据库都不存在该数据的情况下,当访问量达到一个阈值,直接触发降级处理,给用户抛出异常什么的;

7.什么是Redis缓存雪崩?如何解决?(必问)

同一时刻大量缓存失效,导致请求全部打到数据库,引发数据库宕机
解决办法:

  • 1) 缓存数据的过期时间设置固定值+随机值,防止同一时间大量数据过期现象 (在参数中设置过期时间)
  • 2) 采用多级缓存,如加入JVM缓存,Nginx本地缓存,而且不同缓存的过期时间尽可能分散
  • 3) 将热点数据设置为永不过期

8.什么是Redis缓存击穿?如何解决?(必问)

缓存击穿指某个key失效,同一时刻,大量相同请求会直接打到数据库
解决办法:
1) 将热点数据设置为永不过期
2) 采用多级缓存,如加入JVM缓存,Nginx本地缓存,而且不同的缓存的过期时间尽可能分散
3) 采用互斥锁(ReentrantLock)
大概原理就是,多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求线程上使用一个互斥锁锁住它.其他线程走到这一步拿不到锁就快速失败,等第一个线程查询到了数据,然后做缓存.后面的线程进来发现一家有缓存了,就直接走缓存.
Lock lock = new ReentrantLock();
String str = redisTemplate.opsForValue().get(“key”);
if (str == null){
if(lock.tryLock()){
//代表该线程获取到互斥锁
String a = queryById(id);
redistemplate.opsForValue().set(key,a);
Thread.sleep(10);
lock.unLock();//释放锁
}
}

9.数据库和Redis数据如何同步?

1)直接编写业务代码实现,每次修改数据时,删除缓存(让其新缓存)
2)采用MQ同步
3)使用阿里的Canal同步(推荐)

10,Redis的缓存过期策略:

  • 定时删除:创建一个定时器,到时间立即执行删除(对内存友好,因为能保证到期就能删除,但是对cpu不友好);
  • 惰性删除:键过期不管,直到每次获取键的时候检测是否过期,过期就删除(对cpu友好,但是要使用到的时候才会判断是否删除,对内存不友好);
  • 定期删除:隔一段时间检查一次,具体算法决定检查多少删除多少,需要合理设置;

    11,Redis的内存淘汰策略:

12,Redis的5数据类型:

  1. 字符串String;
  2. 哈希Hash;
  3. List集合;
  4. Set集合;
  5. 有序集合Zset;