Redis常见面试题总结(上)

Redis 基础
什么是 Redis?

Redis (REmote DIctionary Server)是一个基于 C 语言开发的开源 NoSQL 数据库(BSD 许可)。与传统数据库不同的是,Redis 的数据是保存在内存中的(内存数据库,支持持久化),因此读写速度非常快,被广泛应用于分布式缓存方向。并且,Redis 存储的是 KV 键值对数据。

为了满足不同的业务场景,Redis 内置了多种数据类型实现(比如 String、Hash、Sorted Set、Bitmap、HyperLogLog、GEO)。并且,Redis 还支持事务、持久化、Lua 脚本、发布订阅模型、多种开箱即用的集群方案(Redis Sentinel、Redis Cluster)。

Redis 没有外部依赖,Linux 和 OS X 是 Redis 开发和测试最多的两个操作系统,官方推荐生产环境使用 Linux 部署 Redis。

Redis为什么这么快?

Redis 内部做了非常多的性能优化,比较重要的有下面 3 点:

  1. Redis 基于内存,内存的访问速度比磁盘快很多;
  2. Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型,主要是单线程事件循环和 IO 多路复用(Redis 线程模式后面会详细介绍到);
  3. Redis 内置了多种优化过后的数据类型/结构实现,性能非常高。
  4. Redis 通信协议实现简单且解析高效。

除了 Redis,你还知道其他分布式缓存方案吗?

  • Dragonfly:一种针对现代应用程序负荷需求而构建的内存数据库,完全兼容 Redis 和 Memcached 的 API,迁移时无需修改任何代码,号称全世界最快的内存数据库。
  • KeyDB: Redis 的一个高性能分支,专注于多线程、内存效率和高吞吐量。

说一下 Redis和 Memcached 的区别和共同点

共同点

  1. 都是基于内存的数据库,一般都用来当做缓存使用。
  2. 都有过期策略。
  3. 两者的性能都非常高。

区别

  1. 数据类型:Redis 支持更丰富的数据类型(支持更复杂的应用场景)。Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。Memcached 只支持最简单的 k/v 数据类型。
  2. 数据持久化:Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memcached 把数据全部存在内存之中。也就是说,Redis 有灾难恢复机制而 Memcached 没有。
  3. 集群模式支持:Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 自 3.0 版本起是原生支持集群模式的。
  4. 线程模型:Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程的多路 IO 复用模型。 (Redis 6.0 针对网络数据的读写引入了多线程)
  5. 特性支持:Redis 支持发布订阅模型、Lua 脚本、事务等功能,而 Memcached 不支持。并且,Redis 支持更多的编程语言。
  6. 过期数据删除:Memcached 过期数据的删除策略只用了惰性删除,而 Redis 同时使用了惰性删除与定期删除。

为什么要用 Redis?

  1. 高性能与低延迟
    • Redis使用内存作为主存储介质,这使得读写操作非常快速,通常达到微秒级响应时间。
    • 它采用了多种优化策略,如多路复用IO和基于事件驱动的异步机制,进一步提升了性能。
  2. 丰富的数据结构支持
    • Redis不仅支持基本的键值对存储,还提供了列表、集合、有序集合、哈希表等多种数据结构。
    • 这为复杂的数据模型提供了便利,使得开发者能更灵活地处理数据。
  3. 持久化机制
    • 虽然Redis主要在内存中操作数据,但它提供了RDB(快照)和AOF(追加文件)两种持久化方式。
    • 这确保了数据不会因为服务器故障而丢失,提高了数据的可靠性和持久性。
  4. 高可用性
    • 通过复制(Replication)、哨兵(Sentinel)和集群(Cluster)模式,Redis能够实现数据的高可用性和自动故障转移。
    • 这增强了系统的稳定性和可靠性,即使在部分节点故障的情况下也能保证服务的连续性。
  5. 消息队列与发布/订阅
    • Redis可以作为简单的消息队列使用,利用发布/订阅模式进行消息的异步传递。
    • 这非常适合解耦系统组件,实现不同服务之间的异步通信。
  6. 缓存
    • Redis是最常用的缓存解决方案之一,能够显著加速数据读取速度,减少数据库负载。
    • 无论是网页缓存、会话缓存还是计算结果缓存,Redis都能提供良好支持。
  7. 会话管理
    • 网站或应用可以将用户会话信息存储在Redis中,以减少对后端数据库的频繁访问。
    • 这提高了响应速度,并简化了会话管理。
  8. 实时数据分析与统计
    • 利用Redis的有序集合,可以快速进行计数、排序等操作。
    • 这适用于实时排名、计数器等需求,为数据分析提供了有力支持。
  9. 限流与防刷
    • 利用Redis的原子操作特性,可以简单有效地实现访问频率限制。
    • 这有助于防止恶意刷请求,保护系统的安全性。
  10. 分布式锁
    • Redis提供SETNX、MULTI/EXEC等命令,可以方便地实现分布式环境下的锁机制。
    • 这解决了并发控制问题,确保了多个节点之间共享资源的一致性。

什么是 Redis Module?有什么用?

目前,被 Redis 官方推荐的 Module 有:

  • RediSearch:用于实现搜索引擎的模块。
  • RedisJSON:用于处理 JSON 数据的模块。
  • RedisGraph:用于实现图形数据库的模块。
  • RedisTimeSeries:用于处理时间序列数据的模块。
  • RedisBloom:用于实现布隆过滤器的模块。
  • RedisAI:用于执行深度学习/机器学习模型并管理其数据的模块。
  • RedisCell:用于实现分布式限流的模块。

Redis 应用

  • 分布式锁:通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。关于 Redis 实现分布式锁的详细介绍,可以看我写的这篇文章:分布式锁详解 。
  • 限流:一般是通过 Redis + Lua 脚本的方式来实现限流。如果不想自己写 Lua 脚本的话,也可以直接利用 Redisson 中的 RRateLimiter 来实现分布式限流,其底层实现就是基于 Lua 代码+令牌桶算法。
  • 消息队列:Redis 自带的 List 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka,有主题和消费组的概念,支持消息持久化以及 ACK 机制。
  • 延时队列:Redisson 内置了延时队列(基于 Sorted Set 实现的)。
  • 分布式 Session :利用 String 或者 Hash 数据类型保存 Session 数据,所有的服务器都可以访问。
  • 复杂业务场景:通过 Redis 以及 Redis 扩展(比如 Redisson)提供的数据结构,我们可以很方便地完成很多复杂的业务场景比如通过 Bitmap 统计活跃用户、通过 Sorted Set 维护排行榜。

如何基于 Redis 实现分布式锁?

一、基于SETNX和EXPIRE命令

  1. SETNX命令:SETNX(Set if Not Exists)是Redis的一个原子操作,用于在key不存在时设置值。如果key已存在,则不做任何操作。这是实现分布式锁的关键命令,因为它能确保在同一时间只有一个客户端能够获得锁。
  2. EXPIRE命令:EXPIRE命令用于为key设置过期时间。这对于避免死锁非常重要,因为即使某个客户端崩溃,锁也会在一定时间后自动释放。

实现步骤

  1. 客户端尝试使用SETNX命令设置锁key。
  2. 如果SETNX命令返回成功(即key被成功设置),则客户端获得锁,并使用EXPIRE命令为锁key设置过期时间。
  3. 如果SETNX命令返回失败(即key已存在),则客户端未获得锁,可以等待一段时间后重试。

注意事项

  • SETNX和EXPIRE命令需要原子性执行,以避免在SETNX成功但EXPIRE失败时导致的死锁问题。通常可以通过Lua脚本来保证这两个命令的原子性。

二、基于SET命令的扩展参数

Redis的SET命令支持多个扩展参数,包括NX、EX/PX等,这些参数可以方便地实现分布式锁。

  • NX:表示key不存在时才能设值成功,即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁后才能获取锁。
  • EX/PX:用于设置key的过期时间,EX以秒为单位,PX以毫秒为单位。

实现步骤

  1. 客户端使用SET key value NX EX/PX命令尝试获取锁。
  2. 如果命令返回成功,则客户端获得锁。
  3. 如果命令返回失败,则客户端未获得锁,可以等待一段时间后重试。

三、Redisson分布式锁

Redisson是一个在Redis基础上实现的Java驻内存数据网格,它提供了高效的分布式锁机制。

实现原理

  1. Redisson使用Lua脚本来保证加锁和解锁操作的原子性。
  2. 在加锁时,Redisson会生成一个随机值作为锁的唯一标识,并将其与锁key一起存储。
  3. 解锁时,Redisson会检查锁的唯一标识是否匹配,只有匹配时才会释放锁。
  4. Redisson还提供了看门狗机制,用于在锁持有者崩溃或失联时自动延长锁的持有时间,防止死锁。

使用步骤

  1. 引入Redisson的依赖。
  2. 配置Redisson客户端。
  3. 使用Redisson提供的锁API(如RLock)进行加锁和解锁操作。

四、RedLock算法

RedLock是Redis官方推荐的一种基于多个Redis实例的分布式锁算法,旨在提供更高的安全性和容错能力。

实现原理

  1. 客户端向多个Redis实例发送加锁请求。
  2. 如果大部分(通常是过半数)Redis实例都成功返回加锁结果,则客户端认为加锁成功。
  3. 解锁时,客户端需要向所有参与加锁的Redis实例发送解锁请求。

注意事项

  • RedLock算法需要多个Redis实例的支持,并且这些实例之间需要保持一定的独立性(如部署在不同的物理节点上)。
  • 在使用RedLock算法时,需要注意网络分区和Redis实例故障等异常情况的处理。

Redis 可以做搜索引擎么?

  • 数据量限制:Elasticsearch 可以支持 PB 级别的数据量,可以轻松扩展到多个节点,利用分片机制提高可用性和性能。RedisSearch 是基于 Redis 实现的,其能存储的数据量受限于 Redis 的内存容量,不太适合存储大规模的数据(内存昂贵,扩展能力较差)。
  • 分布式能力较差:Elasticsearch 是为分布式环境设计的,可以轻松扩展到多个节点。虽然 RedisSearch 支持分布式部署,但在实际应用中可能会面临一些挑战,如数据分片、节点间通信、数据一致性等问题。
  • 聚合功能较弱:Elasticsearch 提供了丰富的聚合功能,而 RediSearch 的聚合功能相对较弱,只支持简单的聚合操作。
  • 生态较差:Elasticsearch 可以轻松和常见的一些系统/软件集成比如 Hadoop、Spark、Kibana,而 RedisSearch 则不具备该优势。

如何基于 Redis 实现延时任务?

Redisson 内置的延时队列具备下面这些优势:

  1. 减少了丢消息的可能:DelayedQueue 中的消息会被持久化,即使 Redis 宕机了,根据持久化机制,也只可能丢失一点消息,影响不大。当然了,你也可以使用扫描数据库的方法作为补偿机制。
  2. 消息不存在重复消费问题:每个客户端都是从同一个目标队列中获取任务的,不存在重复消费的问题。

Redis 数据类型

Redis 中比较常见的数据类型有下面这些:

  • 5 种基础数据类型:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
  • 3 种特殊数据类型:HyperLogLog(基数统计)、Bitmap (位图)、Geospatial (地理位置)。

String 的应用场景有哪些?

String 的常见应用场景如下:

  • 常规数据(比如 Session、Token、序列化后的对象、图片的路径)的缓存;
  • 计数比如用户单位时间的请求数(简单限流可以用到)、页面单位时间的访问数;
  • 分布式锁(利用 SETNX key value 命令可以实现一个最简易的分布式锁);
  • ……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905437.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Training-free layout control with cross-attention guidance

https://zhuanlan.zhihu.com/p/666445024https://zhuanlan.zhihu.com/p/666445024 支持两种模式,1.sd文生图;2.绑定了dreambooth和text inversion的图像编辑。 # ------------------ example input ------------------examples &

‌Spring MVC的主要组件有哪些?

前言 SpringMVC的核心组件包括DispatcherServlet、Controller、HandlerMapping、HandlerAdapter、ViewResolver、ModelAndView等,它们协同工作以支持基于MVC架构的Web应用程序开发。这些组件使得开发人员能够以一种声明式和模块化的方式构建Web应用程序&#xff0c…

Python突破浏览器TLS/JA3 指纹

初识指纹遇到一个网站,忽然发现无论如何如何更换UA和代理请求都是403,curl_cffi 可模拟真实浏览器的 TLS | JA3 指纹。 查看 tls 指纹的网站: https://tls.browserleaks.com/json不同网站的生成的指纹可能有差异,但是多次访问同一个网站生成…

Redis新数据类型

新数据类型 Bitmaps 命令 setbit 实例 getbit 实例 bitcount 实例 bitop 实例 Bitmaps与set 对比 HyperLogLog 命令 pfadd 实例 pfcount 实例 pfmerge 实例 Geospatial 命令 geoadd 实例 geopos 实例 geodist 实例 georadius 实例 Bitmaps Ⅰ.B…

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …

Java Executor ScheduledExecutorService 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledExecutorService & 源码》《Java & Executor & ScheduledExecutorService & 总结》《Java & Executor & ScheduledExecutorService & 问题》 涉及内容 …

C++:继承~派生类以及衍生的多继承与菱形继承问题

C中的继承其实是一个C中的坑,主要体现在其多继承(菱形继承)方面,我们先来了解下继承的概念 一,继承的概念与定义 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许我们在保持原有类特性的基础上进行扩展&#xff0c;增…

Python 从入门到实战43(Pandas数据结构)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;可以熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们学习了NumPy数组操作的相关基础知识。今天学习一下pa…

工程项目智能化管理平台,SpringBoot框架智慧工地源码,实现工程建设施工可视化、智能化的全过程闭环管理。

智慧工地管理系统的建设以“1个可扩展性平台2个应用端3方数据融合N个智能设备”为原则。以“智、保、安、全”为导向&#xff0c;与工程建设管理信息系统、综合安防平台深度集成&#xff0c;构建统一的标准化工地平台&#xff0c;实现现场人员、车辆、项目、安全、进度等方面的…

使用React构建现代Web应用

&#x1f496; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4bb; Gitee主页&#xff1a;瑕疵的gitee主页 &#x1f680; 文章专栏&#xff1a;《热点资讯》 使用React构建现代Web应用 1 引言 2 React简介 3 安装React 4 创建React项目 5 设计应用结构 6 创建组件 7 使用组件…

哈希——哈希表处理哈希冲突的方法

处理哈希冲突 实践中哈希表⼀般还是选择除法散列法作为哈希函数。 当然哈希表无论选择什么哈希函数也避免不了冲突&#xff08;主要作用就是减少冲突&#xff09;&#xff0c;那么插入数据时&#xff0c;如何解决冲突呢&#xff1f;主要有两种两种方法&#xff0c;开放定址法和…

海外云手机是什么?对外贸电商有什么帮助?

在外贸电商领域&#xff0c;流量引流已成为卖家们关注的核心问题。越来越多的卖家开始利用海外云手机&#xff0c;通过TikTok等社交平台吸引流量&#xff0c;以推动商品在海外市场的销售。那么&#xff0c;海外云手机到底是什么&#xff1f;它又能为外贸电商卖家提供哪些支持呢…

Hadoop-001-本地虚拟机环境搭建

一、安装VMware 官方下载VMware&#xff1a; https://vmware.mdsoft.top/?bd_vid5754305114651491003 二、下载镜像文件 阿里云镜像仓库&#xff1a; https://mirrors.aliyun.com/centos/ 本文档使用 CentOS-7-x86_64-DVD-1810-7.6.iso 搭建虚拟机 三、搭建虚拟机 1、编辑…

Oracle视频基础1.1.2练习

1.1.2 需求&#xff1a; 查询oracle组件和粒度大小&#xff0c; select component,granule_size from v$sga_dynamic_components;Oracle SGA 中组件和粒度大小查询详解 在 Oracle 数据库的内存结构中&#xff0c;SGA&#xff08;System Global Area&#xff0c;系统全局区&am…

动态上下文信念(DCB)

DCB&#xff08;动态上下文信念&#xff09;是一个用于累积通过注视获得信息的状态表示组件。它由三个部分组成&#xff1a; Fovea&#xff08;中央凹&#xff09;&#xff1a;接收来自注视位置周围区域的高分辨率视觉输入。Contextual beliefs&#xff08;上下文信念&#xf…

双月生日会:温暖相聚,共庆美好时刻

亲爱的华清远见西安中心的家人们&#xff1a; &#x1f389;&#x1f382; 在这金风送爽的秋日里&#xff0c;我们迎来了9、10月的生日会。在这个特别的日子里&#xff0c;我们聚集一堂&#xff0c;共同庆祝那些在这两个月份里出生的小伙伴们的生日。&#x1f382; 活动现场布…

Junit + Mockito保姆级集成测试实践

一、做好单测&#xff0c;慢即是快 对于单元测试的看法&#xff0c;业界同仁理解多有不同&#xff0c;尤其是在业务变化快速的互联网行业&#xff0c;通常的问题主要有&#xff0c;必须要做吗&#xff1f;做到多少合适&#xff1f;现在没做不也挺好的吗&#xff1f;甚至一些大…

【经典论文阅读11】ESMM模型——基于贝叶斯公式的CVR预估

传统的CVR模型&#xff08;也就是直接对conversion rate建模的模型&#xff09;在实际应用中面临两个问题&#xff08;样本选择偏差与数据稀疏性问题&#xff09;。为了解决这两个问题&#xff0c;本文提出ESMM模型。该模型巧妙地利用用户行为序列去建模这个问题&#xff0c;从…

使用Git进行版本控制的最佳实践

文章目录 Git简介基本概念仓库&#xff08;Repository&#xff09;提交&#xff08;Commit&#xff09;分支&#xff08;Branching&#xff09; 常用命令初始化仓库添加文件提交修改查看状态克隆仓库分支操作合并分支推送更改 最佳实践使用有意义的提交信息定期推送至远程仓库使…

Vision-Language Models for Vision Tasks: A Survey阅读笔记

虽然LLM的文章还没都看完&#xff0c;但是终究是开始看起来了VLM&#xff0c;首当其冲&#xff0c;当然是做一片文献综述啦。这篇文章比较早了&#xff0c;2024年2月份出的last version。 文章链接&#xff1a;https://arxiv.org/abs/2304.00685 GitHub链接&#xff1a;GitHu…