Redis面试题
Redis特性 |
数据类型丰富;支持数据磁盘持久化;支持主从同步;支持分片 |
Redis为什么这么快 |
完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高 数据结构简单,对数据操作也简单 采用单线程,单线程也能处理高并发请求,想多核也可启动多实例 使用多路I/O复用模型,非阻塞IO |
从海量的key中查询出某一固定前缀的key? |
首先摸清数据规模 使用keys指令,可能会造成当前服务阻塞 使用scan 0 match k1* count 10,从下标0开始获取k1前缀开头的key,获取10条数据,返回结果集包含到达的下标,以及返回的key结果集 基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程 以0作为游标开始一次新的迭代,直到命令返回游标0完成一次遍历 不保证每次执行都返回某个给定数量的元素,支持模糊查询 一次返回的数量不可控,只能是大概率符合count参数 |
如何通过Redis实现分布式锁? |
分布式锁需要解决的问题? 互斥性:任何时候只能被一个客户端拥有 安全性:只能由被占用的客户端删除 死锁:获取锁的客户端因为某些原因宕机,而未能释放锁。其他客户端不能再获取锁,而导致死锁 容错:当redis节点出现错误或者宕机,客户端依然能获取锁和释放锁【在redis集群中,假设当前访问的redis节点宕机,则客户端先进行解锁操作,向所有的redis节点发送解锁命令,然后重新获取锁,完成业务操作】 set key value [EX seconds] [PX milliseconds] [NX|XX] EX second:设置键的过期时间为second秒 PX millisecond:设置键的过期时间为millisecond毫秒 NX:只在键不存在时,才对键进行设置操作 XX:只在键已经存在时,对键进行设置操作 SET操作成功完成时,返回OK,否则返回nil 首先通过set key value ex nx设置,只有键不存在时,对key进行操作。如果不存在,则进行加锁操作,value是访问客户端的ID,设置超时时间防止死锁;如果存在则判断value值是否一致,如果不一致则获取key的有效时间,继续等待,每隔一段时间进行访问,直到获取成功;如果存在则重复获取锁,并且记录获取锁的次数,释放锁的时候,需要判断是否是同一个客服端ID,并且只有当获取锁的次数为0时,才可以删除锁,防止外层业务没有锁,导致安全问题 |
大量的key同时过期的注意事项 |
集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象 解决方案:在设置key的过期时间的时候,给每个时间加上随机值 |
如何使用redis做异步队列 |
1. 使用List作为队列,RPUSH生产消息,LPOP消费消息 缺点:不会等待队列里有值才去消费 弥补:可以通过在应用层引入sleep机制去调用LPOP重试 2. BLPOP key timeout:阻塞直到队列有消息或者超时 缺点:只能供一个消费者消费 3. pub/sub:主体订阅者模式 发布者(pub)发送消息,订阅者(sub)接收消息 订阅者可以订阅任意数量的频道 缺点:消息的发布是无状态的,无法保证送达 |
Redis如何实现持久化 |
AOF持久化(保存写状态): 记录下除查询以外的所有变更数据库状态的指令 以append的形式追加保存到AOF文件中【增量】 将Reids的操作日志以追加的方式写入文件 日志重写解决AOF文件大小不断增大的问题,原理如下: 随着AOF文件越来越大,里面会有大部分是重复命令或者可以合并的命令 重写的好处:减少AOF日志尺寸,减少内存占用,加快数据库恢复时间 A. 调用fork()创建一个子进程 B. 子进程把新的AOF写到一个临时文件里,不依赖原来的AOF文件 C. 主进程持续将新的变动同时写到内存和原来的AOF里 D. 主进程获取子进程重写AOF的完成信号,往新的AOF同步增量变动 E. 使用新的AOF文件替换掉旧的AOF文件 redis首先fork()去产生一个子进程,子进程把新的AOF文件写到一个临时文件里,新的AOF的重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析或者进行命令的合并。主进程持续把新的变动写到内存里的buffer,同时也会把这些新的变动写到旧的AOF里面,这样即使重写失败也能保证数据的安全。当子进程完成文件的重写之后,主进程会获得一个信号,然后把内存里的buffer追加到子进程生成的新的AOF文件里。之后用新的AOF文件替换掉原先的AOF文件,这样就完成了一次日志重写的整个过程 子进程在做AOF重写时,会通过管道从父进程读取增量数据并缓存下来,在以RDB格式保存全量数据时,也会从管道读取数据,同时不会造成管道的阻塞。也就是说AOF文件的前半段是RDB格式的全量数据,而后半段是redis命令格式的增量数据。 RDB持久化:在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩 |
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java全新整理八股文 + 场景题 + 算法 精心设计,面试命中率超过80% 专栏优势: 1、问题和答案已经整理到位,答案更专业,可以直接回答,不需要额外总结! 2、场景题讲解清晰,适用于大部分场景的项目,并且持续更新中 3、分享学习心得【知识点的广度和深度,算法有哪些坑,如何准备面试等等】