Redis面试题

1、为什么使用redis(高性能、高并发)

  一、高性能,直接从内存中操作,性能远大于操作db。因为db读取的是磁盘上的文件,一般是机械运动,特别慢。
  二、高并发,因为mysql有链接数量上限,超出了就会挂了。而redis不存在这个问题,为什么呢?因为redis使用的是epoll,而mysql使用的是线程池。epoll抗高并发只要内存足够,可以随意抗。而一个进程创建的线程数是有限制的。

2、使用redis有什么缺点
  一、缓存和数据库双写一致性问题
  二、缓存雪崩问题
  三、缓存击穿问题
  四、缓存的并发竞争问题

3、单线程的redis为什么这么快
一、纯内存操作
二、单线程操作,避免了频繁的上下文切换
三、采用了非阻塞I/O多路复用机制

4、redis的数据类型,以及每种数据类型的使用场景
回答:一共五种
  一、String 计数功能,比如点赞数
  二、哈希 结构化的对象
  三、队列 消息队列
  四、集合 不重复值的集合,比如保存话题里的视频id
  五、有序集合 排行榜topN,比如话题下视频排行。

5、redis的过期策略以及内存淘汰机制
问题一、设置了过期时间,但是时间到了,内存占用率还是比较高
问题二、你redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的?
回答:redis采用的是定期删除+惰性删除策略。
为什么不适用纯定时删除?因为这样做,可能在某一个时间段内存在大量要删除的key,这样很可能影响到高并发业务。

那么定期删除+惰性删除策略是怎么执行的?
  一、redis每100ms随机检查【一批key】,如果发现过期那么就删除。【定期删除】
  二、redis每次获取一个key时候都会检查它是否已经被删除,如果是,那么就删除。【惰性删除】

还是存在问题,在于可能某个key没人获取,但是定时删除没检测出来。这时候需要自己配置删除策略了。
redis.conf 中 maxmemory-policy volatile-lru

noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。【推荐】
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。【不推荐】
allkeys-random:在键空间中,随机移除某个key 【不推荐】


6、redis和数据库双写一致性问题

  一致性问题包括:最终一致性问题、强一致性
  强一致性:不能使用缓存。双写必然存在数据不一致问题。
  最终一致性问题:先写db,然后再删缓存。如果删除缓存失败,那么投递消息队列补偿。

7、如何应对缓存穿透和缓存雪崩问题

缓存击穿:故意请求缓存不存在的数据。
  解决方案一:分布式锁,缓存被击穿,要读数据库时候,加个分布式锁,保证用户只能串行访问db
  解决方案二:异步更新策略,无论结果如何,缓存有没有,都给返回,只是可能返回错误码。同时,异步起一个线程去更新缓存。
  解决方案三:提供一个能迅速判断请求是否有效的拦截机制。。。。布隆过滤器。。

缓存雪崩:同一时间内大量面积缓存失效
  解决方案一:随机失效缓存
  解决方案二:使用互斥锁,使得请求串行化。策略不可行。
  解决方案三:双缓存,没看懂。。。【】

8、如何解决redis的并发竞争问题
  能不能用redis事务?不行,因为集群下redis事务基本无用。
  如果要求请求排序:使用队列串行化,或者设置锁时候将时间戳带上,如果某个系统发现自己的时间戳早于缓存锁中的时间戳,那么什么也不操作即可。
  系统A key 1 {valueA 3:00}
  系统B key 1 {valueB 3:05}
  系统C key 1 {valueC 3:10}

  如果要求请求无序:直接分布式锁即可。

9、redis丢失数据原因
  一、程序bug或人为误操作
  二、因客户端缓冲区内存使用过大,导致大量键被LRU淘汰
  三、主库故障后自动重启,可能导致数据丢失
  五、网络分区的问题,可能导致短时间的写入数据丢失
  六、主从复制数据不一致,发生故障切换后,出现数据丢失
  七、大量过期键,同时被淘汰清理

  解决方案:https://blog.csdn.net/zhanglu1236789/article/details/56485213

原文地址:https://www.cnblogs.com/ccXgc/p/9107415.html