1. 什么是Redis?它主要用来什么的?

Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。

2.Redis的基本数据结构类型

Redis有以下这五种基本类型:

  • String(字符串)
  • Hash(哈希)
  • List(列表)
  • Set(集合)
  • zset(有序集合)

3. Redis为什么这么快?

3.1 基于内存存储实现
Redis基于内存存储实现的数据库,相对于数据存在磁盘的MySQL数据库,省去磁盘I/O的消耗。
3.2 合理的数据编码
譬如:String类型如果存储数字的话,是用int类型的编码
3.3 合理的线程模型

  • I/O 多路复用: IO多路复用其实就是一种同步IO模型,它实现了一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu。
  • 单线程模型: Redis是单线程模型的,而单线程避免了CPU不必要的上下文切换和竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的数据库。所以要慎用如smembers和lrange、hgetall等命令。

IO多路复用程序(这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程)会监听多个Socket,将Socket产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理

Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

4. 什么是缓存击穿、缓存穿透、缓存雪崩?

4.1 缓存击穿问题
缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。缓存击穿和缓存雪崩区别在于击穿针对某一热点key缓存,雪崩则是很多key。

如何避免缓存击穿问题,解决方案就有两种:

  • 使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(edis的setnx()方法或者redisTemplate的setIfAbsent()方法)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。
  • “永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。

4.2 缓存穿透问题
缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。

如何避免缓存穿透呢? 一般有三种方法:

  • 如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。
  • 如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。
  • 使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。

4.2 缓存雪奔问题
缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。
如何避免缓存雪崩问题:

  • 缓存雪奔一般是由于大量数据同时过期造成的。
  • Redis 故障宕机也可能引起缓存雪奔,这就需要构造Redis高可用集群。

5. Redis 过期策略和内存淘汰策略

5.1 Redis的过期策略

  1. 定时过期 每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
  2. 惰性过期 只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
  3. 定期过期 每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

Redis中同时使用了惰性过期和定期过期两种过期策略。

5.2 Redis 内存淘汰策略(逐出算法)
Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。
5.2.1 常用的逐出算法:

5.2.2 影响数据逐出的相关配置

  • maxmemory (最大可使用内存): 占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。
  • maxmemory-samples ( 每次选取待删除数据的个数) : 选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据。
  • maxmemory-policy ( 删除策略) : 达到最大内存后的,对被挑选出来的数据进行删除的策略。

6. Redis 的持久化机制有哪些?

Redis提供了RDB(Redis DataBase)和AOF(append only file)两种持久化机制。

6.1 RDB
RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。RDB触发机制主要有以下几种:

RDB 的优点:

  1. RDB是一个紧凑压缩的二进制文件,存储效率较高
  2. 适合大规模的数据恢复场景,如备份,全量复制等,RDB恢复数据的速度要比AOF快很多

RDB缺点:

  1. 没办法做到实时持久化/秒级持久化。
  2. 新老版本存在RDB格式兼容问题

6.2 AOF
AOF持久化,采用日志的形式来记录每个写操作并追加到文件中,重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题,默认是不开启的。

AOF的优点:

  • 数据的一致性和完整性更高

AOF的缺点:

  • AOF记录的内容越多,文件越大,数据恢复变慢。

7.怎么实现Redis的高可用(三种模式)?

Redis 实现高可用有三种部署模式:主从模式,哨兵模式,集群模式。

7.1 主从模式

主从模式中,Redis部署了多台机器,有主节点,负责读写操作,有从节点,只负责读操作。从节点的数据来自主节点,实现原理就是主从复制机制。
主从复制包括全量复制,增量复制两种
7.1.1全量复制
一般当slave第一次启动连接master,或者认为是第一次连接,就采用全量复制,全量复制流程如下:

redis2.8版本之后,已经使用psync来替代sync,因为sync命令非常消耗系统资源,psync的效率更高。

7.1.2 增量复制
slave与master全量同步之后,master上的数据,如果再次发生更新,就会触发增量复制。
当master节点发生数据增减时,会把用户执行的命令发送到所有的slave节点,让slave节点执行。流程如下:

7.2 哨兵模式

哨兵(sentinel) 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。

7.2.1哨兵的作用(哨兵工作原理):

  • 1.监控
    不断的检查master和slave是否正常运行。
    master存活检测、master与slave运行情况检测
  • 2.通知(提醒)
    当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知。
  • 3.自动故障转移
    断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服 务器地址


注意:
哨兵也是一台redis服务器,只是不提供数据服务,哨兵之间也会相互监控,从而达到高可用。
通常哨兵配置数量为单数。

7.3 cluster集群模式

集群就是使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果。

7.3.1 集群作用:

  1. 分散单台服务器的访问压力,实现负载均衡
  2. 分散单台服务器的存储压力,实现可扩展性
  3. 降低单台服务器宕机带来的业务灾难

8. 使用过Redis分布式锁嘛?有哪些注意点呢?

lua脚本如下:

if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end;

一般情况下,已经可以使用这种实现方式。但是存在锁过期释放了,业务还没执行完的问题(实际上,估算个业务处理的时间,一般没啥问题了)。

错误实现:

  1. 命令setnx + expire分开写:
    执行完setnx加锁,正要执行expire设置过期时间时,进程crash掉或者要重启维护了,那这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以分布式锁不能这么实现。
  2. set ex px nx + 校验唯一随机值,再删除:
    判断当前线程加的锁和释放锁是不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁。

9. 使用过Redisson嘛?说说它的原理

分布式锁可能存在锁过期释放,业务没执行完的问题。有些小伙伴认为,稍微把锁过期时间设置长一些就可以啦。其实我们设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。

当前开源框架Redisson就解决了这个分布式锁问题。我们一起来看下Redisson底层原理是怎样的吧:

只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。

10. MySQL与Redis 如何保证双写一致性

外部链接: redis缓存为什么要延时双删

10.1 缓存为啥是删除,⽽不是更新?
如果是更新,存在分布式事务问题,可能出现修改了缓存,数据库修改失败的情况。只是删除缓存的话,就算数据库修改失败,下次查询会直接取数据库的数据,也不会出现脏数据。
10.2 延时双删是什么?
就是在增删改某实体类的时候,要对该实体类的缓存进行清空,清空的位置在数据库操作方法的前后。

流程:

  • 先删除缓存
  • 再更新数据库
  • 休眠一会(比如1秒),再次删除缓存。

这个休眠时间 = 读业务逻辑数据的耗时 + 几百毫秒。为了确保读请求结束,写请求可以删除读请求可能带来的缓存脏数据。这种方案只有休眠那一会(比如就那1秒),可能有脏数据,一般业务也会接受的。

11. 聊聊Redis 事务机制

Redis通过MULTI、EXEC、WATCH等一组命令集合,来实现事务机制。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

简言之,Redis事务就是顺序性、一次性、排他性的执行一个队列中的一系列命令。

Redis执行事务的流程如下:
开始事务(MULTI)
命令入队
执行事务(EXEC)、撤销事务(DISCARD )

布隆过滤器

布隆过滤器是一种占用空间很小的数据结构,它由一个很长的二进制向量和一组Hash映射函数组成,它用于检索一个元素是否在一个集合中,空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

布隆过滤器原理是?假设我们有个集合A,A中有n个元素。利用k个哈希散列函数,将A中的每个元素映射到一个长度为a位的数组B中的不同位置上,这些位置上的二进制数均设置为1。如果待检查的元素,经过这k个哈希散列函数的映射后,发现其k个位置上的二进制数全部为1,这个元素很可能属于集合A,反之,一定不属于集合A。

Redis经典面试题总结相关推荐

  1. Redis经典面试题

    本文分享一些Redis相关的经典面试题,看下你是不是都掌握了. 文章目录 Redis Redis redis优化策略 redis除了做缓存还能做什么? 说说redis持久化方式?分别优缺点是什么?re ...

  2. 2W字!详解20道Redis经典面试题!(珍藏版)

    前言 金九银十即将到来,整理了20道经典Redis面试题,希望对大家有帮助. 1. 什么是Redis?它主要用来什么的? Redis,英文全称是Remote Dictionary Server(远程字 ...

  3. 2W字详解20道Redis经典面试题(珍藏版)

    给大家整理了20道经典Redis面试题,希望对大家有帮助. 1. 什么是Redis?它主要用来什么的? Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开 ...

  4. 收集Redis 经典面试题

    本文的面试题如下: Redis 持久化机制 缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等问题 热点数据和冷数据是什么 Memcache与Redis的区别都有哪些? 单线程的redis为什么这么快 ...

  5. 2W字!详解20道Redis经典面试题!(珍藏版)二

    9.1 主从模式 主从模式中,Redis部署了多台机器,有主节点,负责读写操作,有从节点,只负责读操作.从节点的数据来自主节点,实现原理就是主从复制机制 主从复制包括全量复制,增量复制两种.一般当sl ...

  6. 2W字 详解20道Redis经典面试题(珍藏版)

    1. 什么是Redis?它主要用来什么的? Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化 ...

  7. Redis 经典面试题:Redis 面试连环炮【Redis必知必会】

    Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行各种刁难. Redis有哪些数据结构? 字符串String.字典Hash.列表List ...

  8. Java经典面试题整理及答案详解(四)

    简介: Java经典面试题第四弹来啦!本节小编整理了关于Java开发框架常见的面试题,希望大家多多怜惜,一起进步- 1.SpringMVC返回值,使用SpringMVC的时候我看到两种风格的开发,一种 ...

  9. java面试题_阿里大厂流出的数百道 Java 经典面试题

    BAT 常问的 Java基础39道常见面试题 1.八种基本数据类型的大小,以及他们的封装类 2.引用数据类型 3.Switch能否用string做参数 4.equals与==的区别 5.自动装箱,常量 ...

最新文章

  1. python使用imbalanced-learn的AllKNN方法进行下采样处理数据不平衡问题
  2. android英文文献翻译,有关android技术英文文献翻译
  3. 线程创建后,立刻调用CloseHandle的原因
  4. iview图表_【技术博客】iview常用工具记录
  5. 动态时间规整-DTW算法
  6. 语句:分支语句、switch case ——7月22日
  7. 帆软地址栏传参,实例
  8. vscode 怎么编辑sphinx_如何在vs Code 中编辑和调试Stata程序
  9. Java 中的几种线程池,你之前用对了吗,互联网 面试官 如何面试
  10. 智汇华云 | 集群自动化部署服务流程之自动化集群配置(下)
  11. Rotate Array旋转数组
  12. [.NET] EF LINQ 按时间对数据分类汇总
  13. plsql去除字段中空格_PLSQL 数据中去掉 字段有空格 回车 换行
  14. 整理了上千个Python类库,简直太酷啦!
  15. Linux下清除磁盘分区及残留raid信息
  16. Java常用类学习笔记
  17. CFLOW-AD:通过条件归一化流量进行实时无监督的异常检测与定位
  18. c 语言 树根 函数专题
  19. JPEG数据转YUV数据应用实例
  20. VB实现向窗口发送按键消息

热门文章

  1. 【笔记】H.265/HEVC 视频编码(二)——数字视频格式
  2. HTML5+CSS大作业——个人图库网页设计(5页)
  3. OpenSceneGraph源码分析:osgQt模块
  4. 8086-小写字母转大写字母
  5. 极限题型二:求数列极限常见题型
  6. 国内有哪些质量高的java社区
  7. 上海5月社保费缴纳时间安排,缴费减免了多少?应该缴纳多少?
  8. 【论文阅读】WaterGAN
  9. ie浏览器的html在哪里,Win10系统下ie浏览器在哪?怎么打开IE浏览器?
  10. 【ESP32】17.DS1302实时时钟模块实验(ThreeWire库 / RtcDS1302库)