1、Redis基本数据类型有哪些?

Redis 是一种基于键值对的NoSQL缓存数据库,key都是由字符串构成的,而它的值主要由string(字符串),hash(哈希),list(列表),set(集合),zset(有序集合)五种基本数据结构构成,除此之外还支持一些其他的数据结构和算法。在开发中,字符串类型是用的最多的数据类型,导致我们忽视了redis的其他四种数据类型,在具体场景下选择具体的数据类型对提升Redis性能有非常大的帮助。

  • String(字符串)

  • Hash(哈希)

  • List(列表)

  • Set(集合)

  • zset(有序集合)


2、Redis为什么这么快?

Redis的速度非常的快,单机的Redis就可以支撑每秒10几万的并发,相对于MySQL来说,性能是MySQL的几十倍。速度快的原因主要有几点:

  1. 完全基于内存操作

  2. C语言实现,优化过的数据结构,基于几种基础的数据结构,Redis做了大量的优化,性能极高

  3. 使用单线程,无上下文的切换成本

  4. 基于非阻塞的IO多路复用机制


3、那为什么Redis6.0之后又改用多线程呢?

Redis使用多线程并非是完全摒弃单线程,Redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。

这样做的目的是因为Redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高Redis的性能。


4、知道什么是热key吗?热key问题怎么解决?

所谓热key问题就是,突然有几十万的请求去访问Redis上的某个特定key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致这台Redis的服务器宕机引发雪崩。

针对热key的解决方案:

  1. 提前把热key打散到不同的服务器,降低压力

  2. 加入二级缓存,提前加载热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的内存淘汰机制。

  1. volatile-lru:从已设置过期时间的key中,移出最近最少使用的key进行淘汰

  2. volatile-ttl:从已设置过期时间的key中,移出将要过期的key

  3. volatile-random:从已设置过期时间的key中随机选择key淘汰

  4. allkeys-lru:从key中选择最近最少使用的进行淘汰

  5. allkeys-random:从key中随机选择key进行淘汰

  6. noeviction:当内存达到阈值的时候,新写入操作报错


7、Redis是单线程还是多线程呢?

Redis不同版本之间采用的线程模型是不一样的,在Redis4.0版本之前使用的是单线程模型,在4.0版本之后增加了多线程的支持。

在4.0之前虽然我们说Redis是单线程,也只是说它的网络I/O线程以及Set 和 Get操作是由一个线程完成的。但是Redis的持久化、集群同步还是使用其他线程来完成。

4.0之后添加了多线程的支持,主要是体现在大数据的异步删除功能上,例如 unlink keyflushdb asyncflushall async


8、为什么Redis在4.0之前会选择使用单线程?而且使用单线程还那么快?

选择单线程个人觉得主要是使用简单,不存在锁竞争,可以在无锁的情况下完成所有操作,不存在死锁和线程切换带来的性能和时间上的开销,但同时单线程也不能完全发挥出多核CPU的性能。

至于为什么单线程那么快我觉得主要有以下几个原因:

  1. Redis 的大部分操作都在内存中完成,内存中的执行效率本身就很快,并且采用了高效的数据结构,比如哈希表和跳表。

  2. 使用单线程避免了多线程的竞争,省去了多线程切换带来的时间和性能开销,并且不会出现死锁。

  3. 采用 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 和 bgsavesave 命令在主线程中执行,会导致阻塞。而 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模式下,节点对请求的处理过程如下:

  1. 通过哈希槽映射,检查当前Redis key是否存在当前节点

  2. 若哈希槽不是由自身节点负责,就返回MOVED重定向

  3. 若哈希槽确实由自身负责,且key在slot中,则返回该key对应结果

  4. 若Redis key不存在此哈希槽中,检查该哈希槽是否正在迁出(MIGRATING)?

  5. 若Redis key正在迁出,返回ASK错误重定向客户端到迁移的目的服务器上

  6. 若哈希槽未迁出,检查哈希槽是否导入中?

  7. 若哈希槽导入中且有ASKING标记,则直接操作,否则返回MOVED重定向


15、了解Redis事务机制吗?

redis通过MULTI、EXEC、WATCH等命令来实现事务机制,事务执行过程将一系列多个命令按照顺序一次性执行,并且在执行期间,事务不会被中断,也不会去执行客户端的其他请求,直到所有命令执行完毕。事务的执行过程如下:

  1. 服务端收到客户端请求,事务以MULTI开始

  2. 如果客户端正处于事务状态,则会把事务放入队列同时返回给客户端QUEUED,反之则直接执行这个命令

  3. 当收到客户端EXEC命令时,WATCH命令监视整个事务中的key是否有被修改,如果有则返回空回复到客户端表示失败,否则redis会遍历整个事务队列,执行队列中保存的所有命令,最后返回结果给客户端

WATCH的机制本身是一个CAS的机制,被监视的key会被保存到一个链表中,如果某个key被修改,那么REDIS_DIRTY_CAS标志将会被打开,这时服务器会拒绝执行事务。


参考链接:

《我想进大厂》之Redis夺命连环11问

Redis面试连环15问相关推荐

  1. java面试八股文之------Redis夺命连环25问

    java面试八股文之------Redis夺命连环25问

  2. 面试官这Redis夺命连环12问,谁顶得住?

    面试官这夺命连环12问,谁顶得住? ⏬ 面试官: 同学,我看你每个项目中都用到了Redis,你能说说你是怎样使用Redis的吗? 小A同学: 主要用来做缓存,分布式Session, 阅读量/点赞数统计 ...

  3. MySQL夺命连环15问,你能坚持到第几问?

    文章目录 前言 一.关系型和非关系型的区别,以及使用场景 二.Mysql索引优缺点 三.给字段加索引最好怎么加? 四.什么情况下会导致索引失效? 五.为什么使用模糊匹配会使索引失效 六.回表查询和索引 ...

  4. Redis面试连环问:集群、复制以及与其他NOSQL数据库的区别?

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 面试官问:您熟悉redis?搭建过redis集群?rediscluster底层的主从复制rdb如何工作的?-- 接下来,就是一 ...

  5. Docker夺命连环15问,你能坚持第几问?

    程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 10 分钟. 来自:blog.csdn.net/weixin_41645135/article 目录 什么是Docker? D ...

  6. 【我想进大厂】Redis夺命连环11问

    来源 | 科技缪缪 责编 | Jerry 说说Redis基本数据类型有哪些吧 字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型.C语言的字符串不记 ...

  7. Redis夺命连环11问

    1. 说说Redis基本数据类型有哪些吧 字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型.C语言的字符串不记录自身的长度信息,而SDS则保存了长 ...

  8. nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】

    Redis面试官喜欢问的,小伙伴们看完暴答面试官!!!  Redis 是什么?都有哪些使用场景?Redis 是一个使用 C 语言开发的高性能键值对(key-value)的内存数据库,性能优秀,数据在内 ...

  9. 面试连环问之Redis分布式锁

    面试连环问之Redis分布式锁 面试连环问之Redis分布式锁 核心 主要介绍 主要代码 1.新建RedisLock 2.使用Redis锁遇到的问题 面试连环问之Redis分布式锁 核心 Redis分 ...

最新文章

  1. 如何在Datawhale开源学习小程序中创建队伍?
  2. 遗传:微生物组数据分析方法与应用
  3. ORACLE 11G 搭建dataguard详细步骤(所有操作总结)
  4. 【案例】爆老师拆解同步网络seo分析思路
  5. 无法启动SQL Server 2005中的SQL Server(MSSQLSERVER)服务--zt
  6. 三、synchronized同步锁
  7. OI造数据以及Lemon评测教程
  8. linux zip 删除源文件,linux zip命令参数及用法详解--linux压缩zip文件命令
  9. 地址总线/数据总线/控制总线的作用
  10. 语音视频自动生成字幕功能介绍
  11. CSDN博客QQ加群、微信
  12. 微信开发工具出现 [渲染层网络层错误]
  13. MySql在Springboot项目中报错errorCode 1045 ,state 28000
  14. 准备离开:致消散的梦想
  15. 体重预测[线性回归]
  16. Android自定义view之围棋动画,真牛皮
  17. 【转载】Windows上那些值得推荐的良心软件-整理 easybcd 引导工具 easyuefi 引导工具...
  18. 复杂网络分析(5)----共引和文献耦合
  19. 最新中国省市区县geoJSON格式地图数据Echarts地图数据
  20. 浅析信号端口中电阻与TVS管对浪涌防护的影响

热门文章

  1. 基于车联网的车辆编队标准现状及展望
  2. 云南小学计算机第4册教案,云教版小学信息技术四年级第4册教案.doc
  3. vue使用echarts实现地图预警展示
  4. python中OS的使用
  5. Centos7 系统硬件检测脚本
  6. PRML读书会第五期——概率图模型(Graphical Models)【上】
  7. 白泽四足机器人ROS+rviz仿真(二)整体行走步态
  8. 超好看个人主页HTML引导页源码
  9. Python视频剪辑基础教程:MoviePy VideoClip详解
  10. java oj题及答案_华为OJ答案(java版)题目2