热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Redis高频的面试题有哪些

这篇文章主要介绍“Redis高频的面试题有哪些”,在日常操作中,相信很多人在Redis高频的面试题有哪些问题上存在疑惑,小编查阅了各式资料,整理

这篇文章主要介绍“Redis高频的面试题有哪些”,在日常操作中,相信很多人在Redis高频的面试题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis高频的面试题有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

通过面试多家大型互联网企业,总结了如下的高频面试题目:

1、redis 过期键的删除策略?

  • 定时删除:在设置键的过期时间的同时,创建一个定时器 timer). 让定时器在键 的过期时间来临时,立即执行对键的删除操作。

  • 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是 否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。

  • 定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键

2、Redus的淘汰策略

redis 内存数据集大小上升到一定大小的时候,就会施行 数据淘汰策略 。redis 提供6种数据淘汰策略:

Redis高频的面试题有哪些

通过淘汰策略也能保证Redis中缓存的都是热点数据。

一个客户端运行了新的命令,添加了新的数据。Redi 检查内存使用情况,如果大于 maxmemory 的限制, 则根据设定好的策略进行回收。

注意这里的 6 种机制,volatile 和 allkeys 规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的 lru、ttl  以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略。

使用策略规则:如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用  allkeys-lru;如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用

allkeys-random

3、Redis分布式锁的实现

Redis的分布式缓存特性使其成为了分布式锁的一种基础实现。通过Redis中是否存在某个锁ID,则可以判断是否上锁。为了保证判断锁是否存在的原子性,保证只有一个线程获取同一把锁,Redis有  SETNX (即SET if Note Exists)和 GETSET (先写新值,返回旧值,原子性操作,可以用于分辨是不是首次操作)操作。

(1)关于setnx:

  • 将 key 的值设为 value ,当且仅当 key 不存在,返回值为1。

  • 若给定的 key 已经存在,则setnx不做任何动作,返回值为0。

(2)关于set:一般操作

  • ex seconds - seconds:设置失效时长,单位秒

  • px - milliseconds:设置失效时长,单位毫秒

  • nx - key不存在时设置value,成功返回OK,失败返回(nil)

  • xx - key存在时设置value,成功返回OK,失败返回(nil)

为了防止主机宕机或网络断开之后的死锁,Redis没有ZK那种天然的实现方式,只能依赖设置超时时间来规避。所以如果使用setnx来实现分布式锁,则实现步骤如下:

  • 先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。

  • 如果在 setnx 之后,执行 expire 之前进程意外 crash 或重启维护, 那么就需要把 setnx 和 expire  合成一条指令来用。

Redis 的 setnx 命令是当 key 不存在时设置 key ,但 setnx 不能同时完成 expire 设置失效时长,不能保证 setnx 和  expire 的原子性。我们可以使用 set 命令完成 setnx 和 expire 的操作,并且这种操作是原子操作。举个例子如下:

案例:设置name=p7+,失效时长100s,不存在时设置 1.1.1.1:6379> set name p7+ ex 100 nx OK 1.1.1.1:6379> get name "p7+" 1.1.1.1:6379> ttl name (integer) 94

从上面可以看出,多个命令放在同一个 redis 连接中并且 redis 是单线程的,因此上面的操作可以看成 setnx 和 expire  的结合体,是原子性的。

4、Redis的Reactor模式

Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。

因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。

Redis高频的面试题有哪些

5、redis支持事务回滚吗?

“ 不支持回滚动作,redis是支持简单事务模式,只能discard,不能rollback ”

Redis在执行事务命令的时候,在命令入队的时候, Redis  就会检测事务的命令是否正确,如果不正确则会产生错误。无论之前和之后的命令都会被事务所回滚,就变为什么都没有执行。

当命令格式正确,而因为操作数据结构引起的错误 ,则该命令执行出现错误,而其之前和之后的命令都会被正常执行。这点和数据库很不一样,这是需注意的地方。

对于一些重要的操作,我们必须通过程序去检测数据的正确性,以保证 Redis 事务的正确执行,避免出现数据不一致的情况。 Redis  之所以保持这样简易的事务,完全是为了保证移动互联网的核心问题一性能。

6、Redis的事务机制及CAS

watch指令在redis事物中提供了CAS的行为。为了检测被watch的keys在是否有多个clients同时改变引起冲突,这些keys将会被监控。如果至少有一个被监控的key在执行exec命令前被修改,整个事物将会回滚,不执行任何动作,从而保证原子性操作,并且执行exec会得到null的回复。

7、Redis和Memcached的区别

Redis的特性:

  • 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

  • 支持丰富数据类型,支持字符串、链表、哈希、集合和有序集合

  • 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

  • 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

与Memcached的区别在于:

  • 存储方式  Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部分存在硬盘上,这样能保证数据的持久性。

  • 数据支持类型 Memcache对数据类型支持相对简单。Redis有复杂的数据类型。

  • 使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。

Redis直接自己构建了VM(Virtual Memory)机制  ,因为一般的系统调用系统函数的话(例如java调用自己的API),会浪费一定的时间去移动和请求。

8、缓存穿透、缓存击穿和缓存雪崩

(1)缓存穿透

查询不存在的数据,缓存中没有数据,数据库也没有数据。因此所有的请求都访问到了数据库,给数据库造成了压力。解决方法如下:

采用布隆过滤器,将所有可能存在的数据,哈希到一个很大的 bitmap 中,一个一定不存在的数据会被 bitmap  拦截调,从而避免了对数据库的查询压力。

如果查询的数据为空,那么直接将空数据也缓存起来并设置较短的过期时间。这样下次访问的时候,就直接返回空值。

(2)缓存击穿

缓存击穿是指缓存过期之后,瞬时间并发客户端特别多查询同一条数据的情况下,导致数据库压力过大。业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load  db,

而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex  key,当操作返回成功时,

再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。类似下面的代码:

public String get(String key) {     String value = redis.get(key);     if (value == null) { // 代表缓存值过期         // 设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db         if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { // 代表设置成功             value = db.get(key);             redis.set(key, value, expire_secs);             redis.del(key_mutex);         }         // 这个时候代表同时候的其他线程已经load db并回设到缓存了,         // 这时候重试获取缓存值即可         else {             sleep(50);             get(key); // 重试         }     } else {         return value;     } }

(3)缓存雪崩

雪崩就是指缓存中大批量热点数据过期后系统涌入大量查询请求,因为大部分数据在Redis层已经失效,请求渗透到数据库层,大批量请求犹如洪水一般涌入,引起数据库压力造成查询堵塞甚至宕机。

解决办法:

将缓存失效时间分散开,比如每个key的过期时间是随机,防止同一时间大量数据过期现象发生,这样不会出现同一时间全部请求都落在数据库层,如果缓存数据库是分布式部署,将热点数据均匀分布在不同Redis和数据库中,有效分担压力,别一个人扛。

让Redis数据永不过期(如果业务准许)。

9、Redis数据倾斜

1、存在bigkey:业务层避免创建bigkey,把集合类型的bigkey拆分成多个小集合,分散保存bigkey  保存了大量集合元素(集合类型),会导致这个实例的数据量增加,内存资源消耗也相应增加。bigkey 的操作一般都会造成实例 IO 线程阻塞,如果 bigkey  的访问量比较大,就会影响到这个实例上的其它请求被处理的速度。

2、slot手工分配不均匀:避免把较多的slot分配到一个实例上,进行槽的迁移

3、存在热点数据:采用带有不同key前缀的多副本方法。 我们把热点数据复制多份,在每一个数据副本的 key  中增加一个随机前缀,让它和其它副本数据不会被映射到同一个 Slot 中。这样一来, 热点数据既有多个副本可以同时服务请求,同时,这些副本数据的 key  又不一样,会被映射到不同的 Slot 中。在给这些 Slot 分配实例时,  我们也要注意把它们分配到不同的实例上,那么,热点数据的访问压力就被分散到不同的实例上了。  热点数据多副本方法只能针对只读的热点数据。如果热点数据是有读有写的话,就不适合采用多副本方法了,因为要保证多副本间的数据一致性,会带来额外的开销。

10、为什么Redis单线程模型也能效率这么高?

  • 纯内存操作;

  • 核心是基于非阻塞的IO多路复用机制;

  • 底层使用C语言实现,一般来说,C 语言实现的程序"距离"操作系统更近,执行速度相对会更快;

  • 单线程同时也避免了多线程的上下文频繁切换问题,预防了多线程可能产生的竞争问题。

11、Redis做异步和延时队列?

一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候,要适当 sleep  一会再重试。如果对方追问可不可以不用 sleep 呢?list 还有个指令叫 blpop,在没有消息的时候,它会阻塞住直到消息到来。如果对  方追问能不能生产一次消费多次呢?使用 pub/sub 主题订阅者模式,可以实现 1:N 的消息队列。

使用 zset(有序集合),拿时间戳作为score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N  秒之前的数据轮询进行处理。

12、Redis的集群策略

(1)Redis主从同步Redis的主从结构一主一从,一主多从或级联结构,复制类型可以根据是否是全量而分为全量同步和增量同步。

(2)Redis哨兵  在主从复制实现之后,如果想对master进行监控,Redis提供了一种哨兵机制,哨兵的含义就是监控Redis系统的运行状态,并做相应的响应。Redis  Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为master,继续提供服务。

(3)Redis Cluster 着眼于扩展性,在单个 redis 内存不足时,使用 Cluster  进行分片存储。在redis-cluster架构中,redis-master节点一般用于接收读写,而redis-slave节点则一般只用于备份,其与对应的master拥有相同的slot集合,若某个redis-master意外失效,则再将其对应的slave进行升级为临时redis-master。

13、 Redis 的同步机制

Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次 bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 rdb  文件全量同步到复制节点,复制节点接受完成后将 rdb 镜像加载到内存。加载完成后,再通知主节点

将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

到此,关于“Redis高频的面试题有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程笔记网站,小编会继续努力为大家带来更多实用的文章!


推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 006_Redis的List数据类型
    1.List类型是一个链表结构的集合,主要功能有push,pop,获取元素等。List类型是一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,List的设 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Givenasinglylinkedlist,returnarandomnode'svaluefromthelinkedlist.Eachnodemusthavethe s ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • 都说Python处理速度慢,为何月活7亿的 Instagram依然在使用Python?
    点击“Python编程与实战”,选择“置顶公众号”第一时间获取Python技术干货!来自|简书作者|我爱学python链接|https:www.jian ... [详细]
author-avatar
清明如月_213
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有