Redis面试
一、redis简介
1. 缓存数据库:实现了对热点技术的高速缓存,提高了应用的响应速度,减少后端压力。
2. 主流应用架构
为了提高性能,在客户端和存储层之间添加一个缓存层。当客户端向后端发送请求时,会先去缓存层查,如果有相关数据就直接返回,如果没有就进行穿透查询,如果存储层有相关数据,就将该数据回写进缓存层,那么当再次请求同样的数据时,可以快速响应。(熔断)当存储层无法提供服务时,可以将客户端的请求,直接送到缓存层,无论有没有获得数据都直接返回,实现在有损情况下提供服务。
3. 缓存中间件--Memcache和Redis的区别
(1)Memcache:代码层类似Hash
a. 支持简单数据类型
b. 不支持数据持久化存储,当服务器无法工作是,数据是无法保存下来的;
c. 不支持主从同步
d. 不支持分片
(2)Redis
a. 数据类型丰富:String,Set,List,Hash,Sorted Set
b. 支持数据磁盘持久化存储;
c. 支持主从
d. 支持分片
4. 为什么Redis能这么快:10w+的QPS(每秒查询次数)
(1)完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
(2)数据结构简单,对数据操作也简单--HashMap
(3)采用单线程,单线程也能处理高并发请求,想多核也可启动多实例
(4)使用多路I/O复用模型,NIO
5. 多路I/O复用模型
(1)FD:File Descriptor,文件描述符
一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射
(2)select系统调用:selector方法返回可读可写的FD个数;selector是负责监听文件是可读还是可写的
(3)Redis采用的I/O多路复用函数:epoll/kqueue/evport/select?
a. Redis会根据平台的不同,选择合适的I/O多路复用函数
b. 优先选择时间复杂度是O(1)的I/O多路复用函数作为底层实现
c. 以时间复杂度为O(n)的select作为保底
d. 基于react设计模式监听I/O事件
二、redis常用数据类型和底层数据结构
1. 供用户使用的数据类型
(1)String:最基本的数据类型,二进制安全
(2)Hash:String元素组成的字典,适合用于存储对象
(3)List:链表,按照String元素插入顺序排序
(4)Set:String元素组成的无序集合,通过hash表实现,不允许重复
(5)Sorted Set:通过分数来为集合中的成员进行从小到大的排序,通过hash表或者skiplist实现
(6)用于计数的HyperLogLog,用于支持存储地理位置信息的Geo
2. 数据类型底层数据结构
(1)SDS - simple synamic string - 支持自动动态扩容的字节数组
(2)list - 链表
(3)dict - 使用双哈希表实现的, 支持平滑扩容的字典
(4)zskiplist - 附加了后向指针的跳跃表
(5)intset - 用于存储整数数值集合的自有结构
(6)ziplist - 一种实现上类似于TLV, 但比TLV复杂的, 用于存储任意数据的有序序列的数据结构
(7)quicklist - 一种以ziplist作为结点的双链表结构,
(8)zipmap - 一种用于在小规模场合使用的轻量级字典结构
三、从海量key里查询出某一固定前缀的key
1. 查询前需要摸清数据规模,即问清楚边界
2. KEYS pattern:查找所有符合给定模式pattern的key
缺点:KEYS指令需要一次性返回所有匹配的key,如果key的数量太大会使服务卡顿。
3. SCAN cursor [M