Redis面试连环15问
1、Redis基本数据类型有哪些?
Redis 是一种基于键值对的NoSQL缓存数据库,key都是由字符串构成的,而它的值主要由string(字符串),hash(哈希),list(列表),set(集合),zset(有序集合)五种基本数据结构构成,除此之外还支持一些其他的数据结构和算法。在开发中,字符串类型是用的最多的数据类型,导致我们忽视了redis的其他四种数据类型,在具体场景下选择具体的数据类型对提升Redis性能有非常大的帮助。
String(字符串)
Hash(哈希)
List(列表)
Set(集合)
zset(有序集合)
2、Redis为什么这么快?
Redis的速度非常的快,单机的Redis就可以支撑每秒10几万的并发,相对于MySQL来说,性能是MySQL的几十倍。速度快的原因主要有几点:
完全基于内存操作
C语言实现,优化过的数据结构,基于几种基础的数据结构,Redis做了大量的优化,性能极高
使用单线程,无上下文的切换成本
基于非阻塞的IO多路复用机制
3、那为什么Redis6.0之后又改用多线程呢?
Redis使用多线程并非是完全摒弃单线程,Redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。
这样做的目的是因为Redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高Redis的性能。
4、知道什么是热key吗?热key问题怎么解决?
所谓热key问题就是,突然有几十万的请求去访问Redis上的某个特定key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致这台Redis的服务器宕机引发雪崩。
针对热key的解决方案:
提前把热key打散到不同的服务器,降低压力
加入二级缓存,提前加载热key数据到内存中,如果redis宕机,走内存查询
5、什么是缓存击穿、缓存穿透、缓存雪崩?
5.1 缓存穿透问题
缓存穿透:读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值的查询请求都会穿透到数据库,这就是缓存穿透。
缓存穿透一般都是这几种情况产生的:
业务不合理的设计,比如大多数用户都没开守护,但是你的每个请求都去缓存,查询某个userid查询有没有守护。
业务/运维/开发失误的操作,比如缓存和数据库的数据都被误删除了。
黑客非法请求攻击,比如黑客故意捏造大量非法请求,以读取不存在的业务数据。
如何避免缓存穿透呢? 一般有三种方法:
1.如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。
2.如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。但是如有有写请求进来的话,需要更新缓存哈,以保证缓存一致性,同时,最后给缓存设置适当的过期时间。(业务上比较常用,简单有效)
3.使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。
5.2 缓存雪奔问题
缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。
缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,即让过期时间相对离散一点。如采用一个较大固定值+一个较小的随机值,5小时+0到1800秒酱紫。
Redis 故障宕机也可能引起缓存雪奔,这就需要构造Redis高可用集群。
5.3 缓存击穿问题
缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。
缓存击穿看着有点像,其实它两区别是,缓存雪奔是指数据库压力过大甚至down机,缓存击穿只是大量并发请求到了DB数据库层面。可以认为击穿是缓存雪奔的一个子集吧。有些文章认为它俩区别,是区别在于击穿针对某一热点key缓存,雪奔则是很多key。
解决方案就有两种:
1.使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。
2. “永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间
6、Redis的过期策略有哪些?
redis主要有2种过期删除策略
惰性删除
惰性删除指的是当我们查询key的时候才对key进行检测,如果已经达到过期时间,则删除。显然,他有一个缺点就是如果这些过期的key没有被访问,那么他就一直无法被删除,而且一直占用内存。
定期删除
定期删除指的是redis每隔一段时间对数据库做一次检查,删除里面的过期key。由于不可能对所有key去做轮询来删除,所以redis会每次随机取一些key去做检查和删除。
那么定期+惰性都没有删除过期的key怎么办?
假设redis每次定期随机查询key的时候没有删掉,这些key也没有做查询的话,就会导致这些key一直保存在redis里面无法被删除,这时候就会走到redis的内存淘汰机制。
volatile-lru:从已设置过期时间的key中,移出最近最少使用的key进行淘汰
volatile-ttl:从已设置过期时间的key中,移出将要过期的key
volatile-random:从已设置过期时间的key中随机选择key淘汰
allkeys-lru:从key中选择最近最少使用的进行淘汰
allkeys-random:从key中随机选择key进行淘汰
noeviction:当内存达到阈值的时候,新写入操作报错
7、Redis是单线程还是多线程呢?
Redis不同版本之间采用的线程模型是不一样的,在Redis4.0版本之前使用的是单线程模型,在4.0版本之后增加了多线程的支持。
在4.0之前虽然我们说Redis是单线程,也只是说它的网络I/O线程以及Set 和 Get操作是由一个线程完成的。但是Redis的持久化、集群同步还是使用其他线程来完成。
4.0之后添加了多线程的支持,主要是体现在大数据的异步删除功能上,例如 unlink key
、flushdb async
、flushall async
等
8、为什么Redis在4.0之前会选择使用单线程?而且使用单线程还那么快?
选择单线程个人觉得主要是使用简单,不存在锁竞争,可以在无锁的情况下完成所有操作,不存在死锁和线程切换带来的性能和时间上的开销,但同时单线程也不能完全发挥出多核CPU的性能。
至于为什么单线程那么快我觉得主要有以下几个原因:
Redis 的大部分操作都在内存中完成,内存中的执行效率本身就很快,并且采用了高效的数据结构,比如哈希表和跳表。
使用单线程避免了多线程的竞争,省去了多线程切换带来的时间和性能开销,并且不会出现死锁。
采用 I/O 多路复用机制处理大量客户端的Socket请求,因为这是基于非阻塞的 I/O 模型,这就让Redis可以高效地进行网络通信,I/O的读写流程也不再阻塞。
9、Redis是如何实现数据不丢失的呢?
Redis数据是存储在内存中的,为了保证Redis数据不丢失,那就要把数据从内存存储到磁盘上,以便在服务器重启后还能够从磁盘中恢复原有数据,这就是Redis的数据持久化。Redis数据持久化有三种方式。
AOF 日志(Append Only File,文件追加方式):记录所有的操作命令,并以文本的形式追加到文件中。
RDB 快照(Redis DataBase):将某一个时刻的内存数据,以二进制的方式写入磁盘。
混合持久化方式:Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的优点。
10、AOF和 RDB的实现原理?
AOF采用的是写后日志的方式,Redis先执行命令把数据写入内存,然后再记录日志到文件中。AOF日志记录的是操作命令,不是实际的数据,如果采用AOF方法做故障恢复时需要将全量日志都执行一遍。
RDB采用的是内存快照的方式,它记录的是某一时刻的数据,而不是操作,所以采用RDB方法做故障恢复时只需要直接把RDB文件读入内存即可,实现快速恢复。
11、RDB做快照时会阻塞线程吗?RDB 做快照的时候数据能修改吗?
Redis 提供了两个命令来生成 RDB 快照文件,分别是 save
和 bgsave
。save
命令在主线程中执行,会导致阻塞。而 bgsave
命令则会创建一个子进程,用于写入 RDB 文件的操作,避免了对主线程的阻塞,这也是 Redis RDB 的默认配置。
save是同步的会阻塞客户端命令,bgsave的时候是可以修改的。
12、Redis如何实现高可用?
Redis实现高可用主要有三种方式:主从复制、哨兵模式,以及 Redis Cluster集群。
主从复制
将从前的一台 Redis 服务器,同步数据到多台从 Redis 服务器上,即一主多从的模式,这个跟MySQL主从复制的原理一样。
哨兵模式
使用 Redis 主从服务的时候,会有一个问题,就是当 Redis 的主从服务器出现故障宕机时,需要手动进行恢复,为了解决这个问题,Redis 增加了哨兵模式实现主从故障自动切换(因为哨兵模式做到了可以监控主从服务器,并且提供自动容灾恢复的功能)。
Redis Cluster(切片集群)
Redis Cluster 是一种分布式去中心化的运行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,从而提高 Redis 服务的读写性能。
13、为什么还需要使用Redis Cluster集群模式呢?
使用哨兵模式在数据上有副本数据做保证,在可用性上又有哨兵监控,一旦master宕机会选举salve节点为master节点,这种已经满足了我们的生产环境需要,为什么还会出现Redis Cluster。
哨兵模式归根节点还是主从模式,在主从模式下我们可以通过增加slave节点来扩展读并发能力,但是没办法扩展写能力和存储能力,存储能力只能是master节点能够承载的上限。所以为了扩展写能力和存储能力,我们就需要引入Redis Cluster集群模式。
14、Redis Cluster怎么实现节点选择的吗?
集群中那么多Master节点,redis cluster在存储的时候如何确定选择哪个节点呢?Redis Cluster采用的是类一致性哈希算法实现节点选择的。
Redis Cluster将自己分成了16384个Slot(槽位),哈希槽类似于数据分区,每个键值对都会根据它的 key,被映射到一个哈希槽中,具体执行过程分为两大步。
根据键值对的 key,按照 CRC16 算法计算一个 16 bit 的值。
再用 16bit 值对 16384 取模,得到
0~16383
范围内的模数,每个模数代表一个相应编号的哈希槽。
每个Redis节点负责处理一部分槽位,假如你有三个master节点 ABC,每个节点负责的槽位如下:
节点 | 处理槽位 |
---|---|
A | 0-5000 |
B | 5001 - 10000 |
C | 10001 - 16383 |
客户端给一个Redis实例发送数据读写操作时,如果这个实例上并没有相应的数据,会怎么样呢?MOVED重定向和ASK重定向了解一下哈
在Redis cluster模式下,节点对请求的处理过程如下:
通过哈希槽映射,检查当前Redis key是否存在当前节点
若哈希槽不是由自身节点负责,就返回MOVED重定向
若哈希槽确实由自身负责,且key在slot中,则返回该key对应结果
若Redis key不存在此哈希槽中,检查该哈希槽是否正在迁出(MIGRATING)?
若Redis key正在迁出,返回ASK错误重定向客户端到迁移的目的服务器上
若哈希槽未迁出,检查哈希槽是否导入中?
若哈希槽导入中且有ASKING标记,则直接操作,否则返回MOVED重定向
15、了解Redis事务机制吗?
redis通过MULTI、EXEC、WATCH等命令来实现事务机制,事务执行过程将一系列多个命令按照顺序一次性执行,并且在执行期间,事务不会被中断,也不会去执行客户端的其他请求,直到所有命令执行完毕。事务的执行过程如下:
服务端收到客户端请求,事务以MULTI开始
如果客户端正处于事务状态,则会把事务放入队列同时返回给客户端QUEUED,反之则直接执行这个命令
当收到客户端EXEC命令时,WATCH命令监视整个事务中的key是否有被修改,如果有则返回空回复到客户端表示失败,否则redis会遍历整个事务队列,执行队列中保存的所有命令,最后返回结果给客户端
WATCH的机制本身是一个CAS的机制,被监视的key会被保存到一个链表中,如果某个key被修改,那么REDIS_DIRTY_CAS标志将会被打开,这时服务器会拒绝执行事务。
参考链接:
《我想进大厂》之Redis夺命连环11问
Redis面试连环15问相关推荐
- java面试八股文之------Redis夺命连环25问
java面试八股文之------Redis夺命连环25问
- 面试官这Redis夺命连环12问,谁顶得住?
面试官这夺命连环12问,谁顶得住? ⏬ 面试官: 同学,我看你每个项目中都用到了Redis,你能说说你是怎样使用Redis的吗? 小A同学: 主要用来做缓存,分布式Session, 阅读量/点赞数统计 ...
- MySQL夺命连环15问,你能坚持到第几问?
文章目录 前言 一.关系型和非关系型的区别,以及使用场景 二.Mysql索引优缺点 三.给字段加索引最好怎么加? 四.什么情况下会导致索引失效? 五.为什么使用模糊匹配会使索引失效 六.回表查询和索引 ...
- Redis面试连环问:集群、复制以及与其他NOSQL数据库的区别?
欢迎关注方志朋的博客,回复"666"获面试宝典 前言 面试官问:您熟悉redis?搭建过redis集群?rediscluster底层的主从复制rdb如何工作的?-- 接下来,就是一 ...
- Docker夺命连环15问,你能坚持第几问?
程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 10 分钟. 来自:blog.csdn.net/weixin_41645135/article 目录 什么是Docker? D ...
- 【我想进大厂】Redis夺命连环11问
来源 | 科技缪缪 责编 | Jerry 说说Redis基本数据类型有哪些吧 字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型.C语言的字符串不记 ...
- Redis夺命连环11问
1. 说说Redis基本数据类型有哪些吧 字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型.C语言的字符串不记录自身的长度信息,而SDS则保存了长 ...
- nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】
Redis面试官喜欢问的,小伙伴们看完暴答面试官!!! Redis 是什么?都有哪些使用场景?Redis 是一个使用 C 语言开发的高性能键值对(key-value)的内存数据库,性能优秀,数据在内 ...
- 面试连环问之Redis分布式锁
面试连环问之Redis分布式锁 面试连环问之Redis分布式锁 核心 主要介绍 主要代码 1.新建RedisLock 2.使用Redis锁遇到的问题 面试连环问之Redis分布式锁 核心 Redis分 ...
最新文章
- 如何在Datawhale开源学习小程序中创建队伍?
- 遗传:微生物组数据分析方法与应用
- ORACLE 11G 搭建dataguard详细步骤(所有操作总结)
- 【案例】爆老师拆解同步网络seo分析思路
- 无法启动SQL Server 2005中的SQL Server(MSSQLSERVER)服务--zt
- 三、synchronized同步锁
- OI造数据以及Lemon评测教程
- linux zip 删除源文件,linux zip命令参数及用法详解--linux压缩zip文件命令
- 地址总线/数据总线/控制总线的作用
- 语音视频自动生成字幕功能介绍
- CSDN博客QQ加群、微信
- 微信开发工具出现 [渲染层网络层错误]
- MySql在Springboot项目中报错errorCode 1045 ,state 28000
- 准备离开:致消散的梦想
- 体重预测[线性回归]
- Android自定义view之围棋动画,真牛皮
- 【转载】Windows上那些值得推荐的良心软件-整理 easybcd 引导工具 easyuefi 引导工具...
- 复杂网络分析(5)----共引和文献耦合
- 最新中国省市区县geoJSON格式地图数据Echarts地图数据
- 浅析信号端口中电阻与TVS管对浪涌防护的影响