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


推荐阅读
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 本文详细介绍了在MySQL中如何高效利用EXPLAIN命令进行查询优化。通过实例解析和步骤说明,文章旨在帮助读者深入理解EXPLAIN命令的工作原理及其在性能调优中的应用,内容通俗易懂且结构清晰,适合各水平的数据库管理员和技术人员参考学习。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 哈希表(Hash Table)是一种高效的查找算法,与传统的链表和树结构相比,其在查找过程中无需进行逐个元素的比较。本文将深入探讨哈希表的基本原理、应用场景以及优化策略,帮助读者全面理解其在实际开发中的优势和局限性。通过实例分析和代码示例,我们将展示如何有效利用哈希表提高数据处理效率,并解决常见的冲突问题。 ... [详细]
  • 投融资周报 | Circle 达成 4 亿美元融资协议,唯一艺术平台 A 轮融资超千万美元 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • Spark与HBase结合处理大规模流量数据结构设计
    本文将详细介绍如何利用Spark和HBase进行大规模流量数据的分析与处理,包括数据结构的设计和优化方法。 ... [详细]
  • com.hazelcast.config.MapConfig.isStatisticsEnabled()方法的使用及代码示例 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 通过使用 `pandas` 库中的 `scatter_matrix` 函数,可以有效地绘制出多个特征之间的两两关系。该函数不仅能够生成散点图矩阵,还能通过参数如 `frame`、`alpha`、`c`、`figsize` 和 `ax` 等进行自定义设置,以满足不同的可视化需求。此外,`diagonal` 参数允许用户选择对角线上的图表类型,例如直方图或密度图,从而提供更多的数据洞察。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
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社区 版权所有