Redis 6.0 保姆级教程(含微服务案例与完整面试题):https://www.yuque.com/yuxuandmbjz/redis

  1. Redis是单线程还是多线程 ?为什么这么设计 ?
 Redis一开始是纯单线程模型,在4.0之后引入了多线程,具体实现是通过多线程方式在后台删除对象、通过 Redis 模块实现的阻塞命令等。在6.0之后又在网络 IO 处理方面上也引入了多线程。一开始使用单线程的原因是 Redis 是基于内存而且使用多路复用技术,单线程速度很快,又保证了多线程的特点。因为没有必要使用多线程。后面引入多线程的原因是读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升,所以变成了多线程。之前用单线程是因为基于内存速度快,而且多路复用有多路复用的作用,现在引入多线程是出于性能上的考虑,对于一些大键值对的删除操作,通过多线程非阻塞地释放内存空间也能减少对 Redis 主线程阻塞的时间,提高执行的效率。单线程指的是工作线程 多线程说的是IO。
  1. 默认是数据库是什么 ? 有几个数据库 ?有什么数据类型 ?怎么启动 ?
默认是0号数据库,一共有16个数据库。数据类型包括:StringList Set  (查看双方共同的信息,比如共同关注的人)Hash (储存经常变动的用户信息)Zset (数据排序)加分的数据类型:Geospatial    (附近的人,二者的距离)Hyperloglog   (统计排除重复的总数)Bitmap        (储存0/1,打卡统计)启动:redis-server redis.conf
进入客户端:redis-cli -p 端口(默认6379)
  1. 介绍一下Redis( 顺带提一下Redis有没有原子性 )?
 Redis的数据类型包括String、List、Set、Hash、Zset、Geospatial、Hyperloglog、BitmapRedis单条命令保证原子性,事务不保证原子性,Redis事务的本质是一组命令的集合。没有隔离级别的概念,所有的命令在事务中并没有被直接执行,只有发起执行命令(Exec)的时候才会执行。开启事务:multi执行事务:exec在事务中编译时异常(命令错误),事务报错无法执行;在事务中语句异常
  1. Redis有没有乐观锁/悲观锁 ?怎么解决乐观锁的冲突 ?
 乐观锁:很乐观,认为什么时候都不会出问题,所以不会上锁! 更新数据的时候去判断一下,在此期间是否有人修改过这个数据,更新的时候比较 version来判断。悲观锁:很悲观,认为什么时候都会出问题,无论做什么都会加锁,性能低下。在值上加上watch开启乐观锁,先unwatch然后重新watch解决锁
  1. 说一下Redis持久化 ,优缺点分别是什么 ?
 Redis持久化包括RDB和AOF,RDB是 Redis database的缩写,它会在指定的时间间隔内将内存中的数据集快照写入磁盘,它恢复时是将快照文件直接读到内存里。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,选择RDB。RDB的触发机制是 满足配置文件的save的规则、执行 flushall、flushdb 命令、退出redis。优点:1、适合大规模的数据恢复! 2、对数据的完整性要不高!缺点:1、需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改数据就没有的了!2、fork进程的时候,会占用一定的内容空间。3.如果没有满足save保存规则,数据就不会被保存,该情况下会造成数据丢失问题。AOF是以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件
但不可以改写文件,改写aof文件会报错,redis启动之初会读取该文件重新构建数据。AOF默认不开启。
优点:1、每一次修改都同步,文件的完整会更加好!2、每秒同步一次,可能会丢失一秒的数据3、从不同步,效率最高的!
缺点:1、相对于数据文件来说,aof 远远大于 rdb,修复的速度也比 rdb 慢!2、Aof 运行效率也要比 rdb 慢,所以我们redis默认的配置就是rdb持久化!
  1. Redis缓存穿透、缓存击穿、雪崩是什么 ? 解决方案 ?
缓存穿透(查不到): 多个用户查询 Redis 和 MySQL 中都不存在的数据,并发量一上去对持久层进行大量读操作,这种就是缓存穿透。解决方案1 :布隆过滤器原理:解决方案2 :在redis设置对应的缓存空对象,有两个缺点:A。缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;B、即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,对需要保持一致性的业务会有影响。缓存击穿(量太大): 指一个key非常热点,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就叫雪崩。解决方案1:设置热点数据永不过期,最安全的但是占空间,内存消耗大,并且不能保持数据最新。解决方案2:加互斥锁(存在代码复杂度增大、存在死锁的风险、存在线程池阻塞的风险)保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。缓存雪崩(Redis数据大量丢失):在某一个时间段,缓存集中过期失效。比如 Redis 宕机!,马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。解决方案1:做集群。解决方案2:限流降级,使用Sentinel或者hytrix进行服务降级、服务垄断。为什么:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。解决方案3:缓存(数据)预热。在正式部署之前,先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
  1. Redis 对于大量的请求怎么样处理 ?
 redis是通过IO多路复用来处理多个客户端请求的
  1. Redis 常见性能问题和解决方案 ?
(1) Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
(2) 如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性, Master 和 Slave 最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即: Master <- Slave1 <- Slave2 <-
Slave3…
  1. 为什么Redis的操作是原子性的,怎么保证原子性的 ?
 对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。
Redis本身提供的所有API都是原子操作,Redis中的事务其实是要保证批量操作的原子性。追问:多个命令在并发中也是原子性的吗?回答:不一定,将get和set改成单命令操作、incr 、使用Redis的事务。
  1. redis的key和value最大值是多少 ?
redis的key和string类型value限制均为512MB。
  1. Redis采用的过期策略是什么 ?过期策略有几种 ?
过期策略分三种:1.定时删除含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除优点:保证内存被尽快释放缺点:若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key。定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器将会有大量的定时器产生,性能影响严重。---------------------------------------------------------------------------------2.惰性删除含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。优点:删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了)缺点:若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)---------------------------------------------------------------------------------3.定期删除含义:每隔一段时间执行一次删除过期key操作。优点:通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用--处理"定时删除"的缺点。定期删除过期key--处理"惰性删除"的缺点。缺点:在内存友好方面,不如"定时删除"在CPU时间友好方面,不如"惰性删除"难点:合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)---------------------------------------------------------------------------------redis采用的是定期删除+惰性删除策略。追问:为什么不用定时删除策略?
回答:定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.追问:定期删除+惰性删除是如何工作的呢?
回答:定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。但redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查因此,如果只采用定期删除策略,会导致很多key到时间没有删除。于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。追问:采用定期删除+惰性删除就没其他问题了么?
回答:不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。
  1. Redis内存淘汰机制有哪些 ?
内存淘汰策略:
(1)volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
(2)volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
(3)volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
(4)volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
(5)allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
(6)allkeys-lfu:从数据集中挑选使用频率最低的数据淘汰。
(7)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
(8)no-enviction(驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。这八种大体上可以分为4中,lru、lfu、random、ttl。
  1. Redis先更缓存还是数据库 ?
推荐先更新数据库,再更新缓存。举个例子:

1、线程A发起一个写操作,第一步写入数据到数据库
2、线程A第二步delete cache
3、线程B发起一个读操作,cache miss
4、线程B从数据库获取最新数据
5、线程B同时set cache
获取到了最新的数据。并发操作例子:

1、线程A发起一个写操作,第一步写入数据到数据库
2、线程B发起一个写操作,第一步写入数据到数据库
3、线程B第二步delete cache
4、线程C发起一个读操作,cache miss
5、线程C从数据库获取最新数据
6、线程C同时set cache
7、线程A第二步delete cache该情况下由于线程A、B最初都把数据写入了数据库,接着都有delete cache,此时如果有线程C来读数据,你会发现不管线程C的动作做任意顺序穿插在A、B动作之间,最后查询数据最差也就是在线程A、B删除cache之前获取到了旧数据,其余都会获取到新数据,并不会影响后来的请求获取到新数据。追问:为什么最后是把缓存的数据删掉,而不是把更新的数据写到缓存里 ?
回答:这么做引发的问题是,如果A、B两个线程同时做数据更新,A先更新了数据库,B后更新数据库,则此时数据库里存的是B的数据。而更新缓存的时候,是B先更新了缓存,而A后更新了缓存,则缓存里是A的数据。这样缓存和数据库的数据会发生不一致。如果先更新缓存再更新数据库就会有问题。
举个例子:

1、线程A发起一个写操作,第一步delete cache
2、此时线程B发起一个读操作,cache miss
3、线程B继续读数据库,读出来一个老数据
4、然后老数据入cache
5、线程A写入了最新的数据这样以后每次从缓存中读到的都是老数据,造成数据不一致。追问:不删除缓存而是直接更新缓存这种可以吗 ?
回答:当然不行

1、线程A发起一个写操作,第一步set cache
2、线程B发起一个写操作,第一步set cache
3、线程B写入数据到数据库
4、线程A写入数据到数据库这样以后每次从缓存中读到的都是线程B设置的数据,但数据库中存储的是线程A写入的数据,导致数据不一致。
可看到先操作缓存不论是先删除缓存还是先更新缓存都会发生数据不一致的情况,所以不推荐这两种做法。

Redis 5.0.8+常见面试题(单线程还是多线程、先更新缓存还是数据库、雪崩穿透击穿解决办法...)相关推荐

  1. Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)

    Java多线程面试题以及答案整理[最新版]Java多线程高级面试题大全(2021版),发现网上很多Java多线程面试题都没有答案,所以花了很长时间搜集,本套Java多线程面试题大全,汇总了大量经典的J ...

  2. Redis常见面试题总结

    Redis常见面试题 持久化方式有哪些?有什么区别? redis持久化方案分为RDB和AOF两种. RDB RDB持久化可以手动执行也可以根据配置定期执行,它的作用是将某个时间点上的数据库状态保存到R ...

  3. 七天玩转Redis 第七天打卡 Redis常见面试题及课程总结

    七天玩转Redis 第七天打卡 Redis常见面试题及课程总结 主要总结点: 截止到今天,七天玩转Redis课程就马上结束了,学以致用,那么学会了Redis,在找工作时会有哪些面试官爱问的问题呢? 一 ...

  4. 面经 | Redis常见面试题

    Redis 常见面试题 目录结构: 文章目录 Redis 常见面试题 数据结构 String 哈希 List Set Zset 有序集合 持久化机制 RDB快照 AOF 混合使用 Redis为什么要线 ...

  5. Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3

    Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3 总览 问题 详解 String.intern()的作用 link LeetCode的Two Sum题 ...

  6. Redis常见面试题(缓存击穿、穿透、雪崩)

    Redis常见面试题(缓存击穿.穿透.雪崩) 击穿 场景: 一般由于redis中的数据到期,同时并发用户特别多,此时大量请求压到数据库上. 解决思路: 根据redis是单进程单实例的特性,当高流量进入 ...

  7. 【面试题】Redis篇-常见面试题p1

    [面试题]Redis篇-常见面试题p1 备战实习,会定期的总结常考的面试题,大家一起加油!

  8. 前端常见面试题之----js单线程,微任务宏任务

    js单线程,微任务宏任务 前言 一.什么是单线程? 二.为什么JS是单线程? 三.任务队列 1. 什么是任务队列 2. 什么是微任务宏任务 四.常见面试题例子 总结 前言 他来了他来了,前端必问题之一 ...

  9. 常见面试题之缓存雪崩、缓存击穿、缓存穿透(redis)

    前言 Hello,everybody,我是asong,今天与大家一起来聊一聊面试中几个常见的缓存问题.为什么会突然想做一篇这个文章呢,今天翻了一下我当初准备面试时整理的一些资料,发现缓存在面试中占比还 ...

最新文章

  1. Python+OpenCV 图像处理系列(4)—— 图像像素的读写、算术运算、逻辑运算及像素的统计
  2. 20Composite(组合)模式
  3. LeetCode:345. Reverse Vowels of a String
  4. 重新解析 REST Service(REST Service 的最佳实践,第 1 部分)
  5. gcc / -L 和 -Wl,-rpath 区别
  6. PHP的static
  7. python 建筑建模_不可错过的python 街道数据爬取和分析神器!
  8. mysql客户端路由方式_20.3 在InnoDB 集群中 使用MySQL 路由
  9. 事业单位考试高频考点一:马克思主义基本原理
  10. angular4 跨域携带cookie的设置
  11. 管理感悟:不要别人扫自己的屁股
  12. dos命令实现无限弹窗
  13. springboot自动装配流程图
  14. 荣耀手机两个android文件夹,华为手机文件管理中,这几个文件夹可以任意删除,其他的千万不要乱删!...
  15. mysql和jdbc(韩)
  16. 编程技巧│使用 python 操作手机 app 超详细步骤
  17. matlab中integrator,matlab:Simulink Integrator的理解
  18. MacBook软件安装和更新与卸载
  19. Linux命令分隔符
  20. Python计算圆的周长与面积

热门文章

  1. 华为在推荐系统中的前沿技术研究与落地(附PPT下载链接)
  2. MoSE: 多任务混合序列专家模型
  3. 基于scikit-learn的随机森林调参实战
  4. js 拉勾网效果_python爬取拉勾网职位数据
  5. Leetcode刷题系列汇总
  6. python接口自动化(八)--发送post请求的接口(详解)
  7. 【五】Jmeter:函数助手
  8. python文本分类算法_python编写朴素贝叶斯用于文本分类
  9. 线程java作用_java线程介绍(原创)
  10. mysql必背_必背的mysql语句.doc