redis 面试题

1. 为什么Redis很快

  1. 基于内存操作,速度比磁盘操作快得多
  2. 单线程,避免了多线程的线程安全操作,避免了上下文切换
  3. 缓存了时间戳,渐进式hash

2. Redis的使用场景

  1. string:缓存、分布式session、计数器
  2. hash:存储对象
  3. list:消息队列:通过lpush命令让生产者客户端从列表左边插入消息,而brpop命令让多个消费者客户端从队列为阻塞式抢占队列尾部的消息
  4. set:交集,共同好友筛选
  5. zset:排行榜
  6. bitmaps(位图):布隆过滤器:通过几个hash函数,对一个key进行哈希,将命中的bitmaps(实际上是一个二进制数组)的桶值修改为1,在确定是否存在某个key时,通过同样的hash函数,找到对应的位置,如果都为1,判断该值存在,如果存在一个位置为0,则判断该值不存在,都为1时不一定存在,存在0时,一定不存在,通过这种方式可以防止缓存穿透。

3. 为何6.0之前使用单线程而之后引入了多线程

  1. 6.0之前使用单线程的原因是因为Redis的性能瓶颈不在上下文的切换上,而是在与CPU计算和网络请求上,无需使用多线程操作
  2. 6.0之后引入的原因是为了解决一下io密集型的任务,比如aof日志,rdb快照的持久化,其他批量操作

4. Redis的高级功能有哪些

  1. 慢查询:快速定位系统中的慢查询操作
  2. watch命令:相当于乐观锁,确保事务读取时数据没有被其他事务修改,如果修改则不读取
  3. 分布式锁:通过setnx命令,多个客户端set同一个key,如果key已经存在,则set失败,由此实现互斥
  4. 高性能与高并发:主从复制架构可以做到读写分类
  5. 哨兵模式:如果主节点发生故障,哨兵可以将从节点指定为主节点,主节点恢复后变为从节点

5. 为什么引入Redis

  1. 高并发:
    Redis支持主从复制,主节点复制写操作,而从节点复制读操作,读写分离,可以支持高并发场景,当主节点出现故障的时候,通过哨兵模式,切换主节点,保证系统正常使用
  2. 高性能:Redis是基于内存的操作,速度十分快速

6. Redis事务

Redis事务通过两个命令完成:

  1. multi:开启事务
  2. exec:退出事务
    将要执行的事务操作放在两个命令之间即可,此外还有一个discard命令用于回滚,但是Redis事务只能对基本的语法错误进行回滚,运行时错误无法回滚

7. Redis的过期策略

  1. 定时过期:定时从设置了过期时间的数据字典里面读取一组key(默认20个),删除其中过期了的key,默认是10次/s读取,当一组key里面有超过四分之一是过期的,则再读取一组(贪心算法)
  2. 惰性过期:在使用到key时才回去判断是否过期

从库的过期策略:主库中的key过期后,会在给从库发送的同步文件中增加一条del命令,删除过期key

8. 缓存淘汰机制

当Redis分配的内存满了,会开始频繁与磁盘进行交互,导致性能下降
Redis可以通过设置maxmemory修改最大内存空间
缓存淘汰机制:

  1. Noevication:默认情况下不淘汰key,此时只许读不许写
  2. volatile_lru:从设置了过期时间的key中淘汰最少使用的key
  3. volatile_ttl:从设置了过期时间的key中淘汰剩余存活时间最短的key
  4. volatile_random:从设置了过期时间的key里面随机淘汰key
  5. allkeys_lru:从所有key里面淘汰最少使用的key
  6. allkeys_random:从所有key里面随机淘汰key

9. 缓存雪崩、缓存击穿、缓存穿透

  1. 缓存雪崩
  • 缓存中的热点数据同一时间失效,导致大量请求请求到数据库,造成系统崩溃
  • 解决方案:
    . 热点数据不设置过期时间
    . 使用主从复制架构,提高系统的可用性,主节点故障的时候,从节点提供服务
  1. 缓存击穿
  • 数据库中存在的数据而缓存中没有,在高并发情况下,大量请求直接落到数据库或其他缓存中,导致数据库负担过大,影响性能
  • 解决方案:
    . 使用lru缓存淘汰机制 ,及时将不常用的数据从缓存中删除,给热点数据提供缓存空间
    . 使用布隆过滤器的缓存预热功能,提前将热点数据加载到缓存中
    . 使用分布式锁,让同一时间只有一个请求可以访问同一数据
  1. 缓存穿透
  • 缓存中没有且数据库中也没有的数据被大量请求,导致数据库负担过大,通常是恶意请求
  • 解决方案:
    . 使用缓存空对象,将空对象缓存到缓存中,返回空对象,而不再请求数据库
    . 使用布隆过滤器,对恶意请求进行拦截

10. Redis分布式锁

  1. 通过setnx设置key,同一时间只有一个客户端能设置该key,如果设置成功则返回1,否则返回0,由此实现互斥
  2. 存在一个客户端宕机,key无法释放,其他客户端一直不能set的情况,可以通过设置过期时间来解决
  3. 过期时间结束而客户端没有完成业务处理的情况,可以加入看门狗来解决,当客户端设置过期时间后,开启一个守护线程,定时检查剩余过期时间,如果业务没有完成,而过期时间将要结束,则自动续期

11. bigkey

  1. 定义:字符串类型的key存储了超过10kb的字符串(通常来说);其他如list,hash,set,zset存储了太多元素
  2. 危害:空间分布不均;大容量造成网络堵塞
  3. 解决:拆分

12. 如何解决key冲突

  1. 在key设计上:添加唯一标识,如数据库ID
  2. 代码实现上:使用分布式锁

13. 如何提高缓存的命中率

  1. 提前加载,缓存预热
  2. 增加缓存可用的内存空间

14. Redis持久化

  1. aof
    以独立日志的方式,将每一次写操作记录到日志中,每次重启时加载
    缺点:性能差
  2. rdb
    以快照的方式备份数据
    缺点:两次快照之间有空窗

15. 为什么Redis使用内存作为工作空间

  1. 内存中的操作速度远高于磁盘中
  2. 内存价格不再那么贵,性价比提高
  3. 内存中的数据可以持久化到磁盘中
  4. 即使内存满了也有内存淘汰机制保证系统正常运行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值