【Java面试题】框架篇——Redis

news2025/1/13 7:32:45

文章目录

      • Redis的使用场景
      • Redis支持的数据类型
      • 如何在Redis中实现分布式锁
      • Redis和Mysql的事务有什么区别?
      • Redis缓存穿透如何解决?
      • Redis缓存雪崩如何解决?
      • 什么是缓存击穿,如何解决?
      • Redis是单线程模式的,为什么还那么快?
      • Redis数据持久化的方式?
      • Redis中分布式锁的特征有哪些?

Redis的使用场景

Redis是一种高性能的内存键值存储数据库,常用于以下场景:

1. 缓存:Redis可以作为缓存系统使用,将常用的数据缓存到内存中,提高访问速度。例如,可以将热点数据、频繁访问的数据等缓存到Redis中,减少对后端数据库的访问压力。

2. 消息队列:Redis支持发布-订阅模式,可以作为轻量级的消息队列使用。例如,可以将用户提交的消息、网站的注册验证信息等发布到Redis中,并通过订阅机制进行处理。

3. 计数器:Redis提供了原子性的操作,可以用于实现计数器功能。例如,可以使用Redis的incr命令对某个键进行自增操作,实现访问次数统计等功能。

4. 排行榜:Redis可以作为排行榜系统使用,支持对不同维度的数据进行排名和统计。例如,可以使用有序集合(sorted set)类型存储用户的积分、点赞数、评论数等信息,并通过分页查询等方式实现排行榜功能。

5. 分布式锁:Redis提供了分布式锁的功能,可以用于实现分布式系统中的互斥操作。例如,在多个进程或线程同时访问同一个资源时,可以使用Redis的setnx命令获取分布式锁,保证只有一个进程或线程能够访问该资源。

6.基于Redis实现共享session

总之,Redis具有高性能、高可用性、易扩展性等特点,适用于各种需要快速读写数据的场景。

Redis支持的数据类型

Redis是一种高性能的内存键值存储数据库,支持多种数据类型。以下是Redis中的五种基本数据类型:

1. 字符串(String):字符串是Redis中最简单的数据类型,可以存储任何二进制数据,包括文本、图片、音频等。字符串类型的值最大可存储512MB。

2. 列表(List):列表是一个双向链表结构,可以快速地在头部和尾部进行插入和删除操作。列表内部的元素是字符串类型。

3. 集合(Set):集合是无序的、不重复的元素集合,支持交、并、差集等操作。集合内部的元素是字符串类型。

4. 有序集合(Sorted Set):有序集合是集合的一种特殊形式,每个成员都与一个分数相关联,可以按分数从小到大排序。有序集合内部的元素同样是字符串类型。

5. 哈希表(Hash):哈希表是一种键值对映射的数据结构,支持添加、删除、查询等操作。哈希表内部的键和值都是字符串类型。

这些基本数据类型提供了Redis最基本的存储和处理能力,同时也支持一些高级的数据类型,如位图、HyperLogLog等,可以满足不同场景下的需求。

在这里插入图片描述

如何在Redis中实现分布式锁

在Redis中实现分布式锁通常有两种方式:使用Redis的setnx命令和使用Redis的分布式锁框架。

1. 使用Redis的setnx命令实现分布式锁

使用setnx命令可以在Redis中实现一个简单的分布式锁,具体步骤如下:

(1)客户端向Redis发送加锁请求,使用SETNX命令将一个特定的键值对设置到Redis中,如果该键不存在,则表示获取到了锁;

(2)如果获取到了锁,客户端执行业务逻辑;

(3)客户端执行完业务逻辑后,使用DEL命令删除之前设置的键值对,释放锁。

需要注意的是,使用setnx命令实现分布式锁时,需要考虑以下几点:

  • 如果多个客户端同时发送加锁请求,只有一个客户端能够成功获取到锁;

  • 如果某个客户端崩溃或意外退出,其他客户端仍然可以继续访问共享资源;

  • 如果需要过期时间,可以使用EXPIRE命令设置键的过期时间。

    1. 使用Redis的分布式锁框架实现分布式锁

除了使用setnx命令外,还可以使用一些开源的Redis分布式锁框架来实现分布式锁。常见的Redis分布式锁框架包括Redisson、Jedis、Lettuce等。这些框架都提供了简单易用的API接口,可以方便地实现分布式锁的功能。

以Redisson为例,使用Redisson实现分布式锁的步骤如下:

(1)引入Redisson依赖;

(2)创建RedissonClient对象;

(3)使用RLock接口获取分布式锁;

(4)执行业务逻辑;

(5)使用Unlock接口释放锁。

需要注意的是,不同的Redis分布式锁框架可能有不同的使用方法和实现细节,具体使用方法需要参考相应的文档说明。

Redis和Mysql的事务有什么区别?

Redis和Mysql是两种不同的数据库类型,它们在事务处理方面有以下区别:

1. 事务的原子性不同:Redis使用基于命令的事务模型,即每个命令被视为一个单独的事务。如果一个命令执行失败,整个事务将被回滚。而Mysql使用基于表的事务模型,即所有对数据库的操作都被视为一个事务。如果一个操作失败,整个事务将被回滚。

2. 隔离级别不同:Redis支持读写锁和单例模式等隔离级别,可以根据实际需求进行选择。而Mysql支持四个隔离级别:未提交读(READ UNCOMMITTED)、已提交读(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。

3. 持久化方式不同:Redis通常不需要持久化,因为它是一种内存数据库。而Mysql需要通过定期备份或日志来保证数据的持久性。

4. 事务处理的复杂性不同:由于Redis是基于命令的事务模型,因此它的事务处理相对简单。而Mysql的事务处理较为复杂,需要考虑多个数据表之间的关系以及锁定机制等因素。

总之,Redis和Mysql在事务处理方面有一些不同之处,具体使用哪种数据库应该根据实际需求来选择。如果需要高并发、低延迟的应用场景,可以考虑使用Redis;如果需要支持复杂的事务处理和高可靠性的数据存储,可以使用Mysql。

Redis缓存穿透如何解决?

Redis 缓存穿透是指查询缓存和数据库中都不存在的数据,但是访问了该数据所在的数据库,导致大量请求直接打到数据库上,使得数据库负载过高,甚至宕机。为了解决这个问题,可以采用以下几种方法:

  1. 布隆过滤器(Bloom Filter):布隆过滤器是一种空间效率极高的随机数据结构,它能快速判断一个元素是否可能存在于集合中。可以将 Bloom Filter 与 Redis 缓存一起使用,当请求的数据在 Redis 缓存中不存在时,先去查询数据库,如果查询结果为空,则将数据写入 Redis 缓存中并返回空对象;如果查询结果不为空,则直接返回查询结果。这样可以有效地避免缓存穿透问题。

  2. 缓存空对象:当请求的数据在 Redis 缓存中不存在时,可以直接返回一个空对象,而不是一个空字符串或者 null。这样可以保证代码的健壮性,并且不会对后续的业务造成影响。

  3. 设置短期过期时间:对于一些高频率访问的数据,可以设置较短的过期时间,这样即使缓存未命中,也不会一直占用缓存空间。同时,当缓存中的数据发生变化时,需要及时更新缓存。

  4. 使用互斥锁:当多个线程同时访问同一个数据时,可能会出现缓存穿透的问题。可以使用互斥锁来避免这种情况的发生。当一个线程要访问某个数据时,首先获取互斥锁,然后查询数据库并将数据存入 Redis 缓存中。如果查询结果为空,则释放互斥锁并返回空对象;否则将数据存入 Redis 缓存中并继续处理其他请求。

总之,Redis 缓存穿透是一个常见的问题,可以通过布隆过滤器、缓存空对象、设置短期过期时间和使用互斥锁等方法来解决。需要根据具体情况选择合适的方法来应对不同的场景。

在这里插入图片描述

关于缓存穿透、雪崩、击穿问题可参考链接:https://juejin.cn/post/7185923117611483196

Redis缓存雪崩如何解决?

Redis缓存雪崩是指在某个时间点,缓存中大量数据同时失效,导致请求直接打到数据库上,使得数据库负载过高,甚至宕机。为了解决这个问题,可以采用以下几种方法:

  1. 设置热点数据永不过期:对于业务访问频率较高的数据,可以设置永不过期,这样即使缓存失效,也不会对业务造成太大的影响。

  2. 分布式锁控制:使用分布式锁来控制缓存的访问和更新操作,避免多个线程同时操作同一个缓存,导致缓存雪崩。当一个线程要访问某个数据时,首先获取分布式锁,然后查询数据库并将数据存入缓存中;释放分布式锁并返回结果。

  3. 缓存预热:在系统启动时,可以将一些热点数据预先加载到缓存中,并设置较长的过期时间。这样可以避免在系统正式运行时出现缓存雪崩的情况。

  4. Redis集群:使用 Redis 集群来分散缓存的访问压力,提高系统的可用性和稳定性。Redis 集群可以将缓存数据分片存储在多个节点上,避免单点故障和缓存雪崩的问题。

  5. 数据分区:将数据按照一定的规则进行分区,每个分区的数据独立存储,互不干扰。这样即使某个分区的数据失效,也不会影响其他分区的使用。

总之,Redis缓存雪崩是一个常见的问题,可以通过设置热点数据永不过期、使用分布式锁、缓存预热、Redis集群和数据分区等方法来解决。需要根据具体情况选择合适的方法来应对不同的场景。

在这里插入图片描述

什么是缓存击穿,如何解决?

缓存击穿也称为热Key问题是指在 Redis 中,Redis中一个热点key在失效的同时,大量的请求过来,从而会全部到达数据库,压垮数据库

解决方案:

1.互斥锁:线程1先发来请求,并且获取到了互斥锁。这时线程1就可以去查询数据库,接着将查询到的数据缓存到redis中,最后记得释放锁,不然以后别的线程无法访问数据库。如果在线程1获取互斥锁成功并且还未重建缓存、释放互斥锁的时候,线程2的请求到达,那么线程2无法在redis中获取到缓存,无法获取到互斥锁,那么我们就让线程休眠一会,比方休眠50毫秒,再让线程2去查询缓存,如果还是查询不到,那么再重新休眠,再重新查询。

2.逻辑过期,意味着永不过期。缓存击穿问题产生的原因是某个热点key过期了,请求都打到数据库了,造成数据库压力过大。因此我们可以提前准备一个不过期的热点key (比如参加活动的商品),不设置它的过期时间,将这个key保存到redis中,这样理论上总能命中redis。那是怎么判断这个key逻辑上过期了?答案是这个key的value存储一个过期时间,我们判断这个key是否过期的依据,就是这个key的value保存的过期时间。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Redis是单线程模式的,为什么还那么快?

​ Redis 之所以能够实现非常高的性能,主要是因为其采用了一些优秀的设计和技术,使得单线程的处理能力得到了极大的提升。

​ 首先,Redis 采用了基于内存的数据存储方式,避免了磁盘 I/O 的开销,从而大大提高了数据的读写速度。同时,Redis 还采用了多种数据结构,如哈希表、有序集合等,这些数据结构的特殊性质也对性能有很大的影响。

​ 其次,Redis 采用了异步非阻塞式的 I/O 模型,通过事件循环机制来处理客户端的请求和响应。这种模型可以避免由于网络连接等原因导致的阻塞和延迟,从而提高 Redis 的并发处理能力。

​ 此外,Redis 还采用了一些优化策略,如使用多个 CPU 核心、使用多路复用技术、使用批量操作等,这些都可以帮助 Redis 提高性能。

​ 总之,Redis 能够实现高性能的原因主要是因为其采用了基于内存的数据存储方式、异步非阻塞式的 I/O 模型、多种高效的数据结构和优化策略等多种因素的综合作用。

Redis数据持久化的方式?

Redis提供了两种持久化方式:RDB(Redis数据库)快照和AOF(Append-Only File)日志。

1. RDB持久化:

RDB持久化是将Redis内存中的数据集写入磁盘的一种方式。它可以在指定的时间间隔内自动执行,也可以手动执行。在执行RDB持久化时,Redis会将内存中的数据集转换为二进制文件,并将其保存到磁盘上。RDB持久化的优点是可以将内存中的数据集快速备份到磁盘上,缺点是可能会丢失最近一次操作的数据。

要启用RDB持久化,请在Redis配置文件中设置以下选项:

save 900 1
save 300 10
save 60 10000

上面的示例将每900秒执行一次完整的RDB快照,每300秒执行一次部分快照,每60秒执行一次增量快照。另外,您还可以使用BGSAVE命令手动执行RDB持久化。

1. AOF持久化:

AOF持久化是将Redis服务器对客户端的所有写操作记录到一个日志文件中的一种方式。当Redis服务器重启时,它会重新执行所有以前的写操作来重建数据集。AOF持久化的优点是可以保证数据的可靠性和一致性,缺点是可能会占用大量的磁盘空间。

要启用AOF持久化,请在Redis配置文件中设置以下选项:

appendonly yes
dir /var/lib/redis/aof
maxmemory-policy allkeys-lru
appendfsync always
save 300 10
save 60 10000

上面的示例将每个键的修改都添加到AOF文件中,并在每次写操作后保存当前时间戳和修改的数量。此外,还设置了最大内存策略、刷新策略和保存策略。

Redis中分布式锁的特征有哪些?

在这里插入图片描述

实现分布式锁的方式:[https://juejin.cn/post/6936956908007850014

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python超大数计算

Python超大数计算 介绍 在日常编程中,我们常常需要处理大量数据。这些数据可以是普通的整数或浮点数,但有时候我们需要计算的数据可能会超出计算机处理的数值范围。这时,我们需要使用更为高级的算法来进行超大数计算。 Python语言因为其简…

【Java】 Java 中处理 null 或缺失数据

本文仅供学习参考! 相关教程地址: https://juejin.cn/post/7234924083842154556 https://cloud.tencent.com/developer/article/1107739?areaSource106005.3 https://www.developer.com/java/null-data-java/ 将某些内容表示为空白或不存在始终是编程中…

TX Text Control 31 sp3 for ActiveX-VB6-Crack

Visual Basic 6 应用程序的文档处理 适用于 Visual Basic 6 和基于 COM 的语言的综合文字处理和报告 视窗用户界面 功能齐全的文档编辑器 TX Text Control 是一款免版税、完全可编程的丰富编辑控件,它在专为 Visual Studio 设计的可重用组件中为开发人员提供了广泛的…

数字空间【高校版】上线

WRITE-BUG团队一直在致力于推动科技创新与科研学习数字化建设,为学生的学习、老师的工作,插上数字化的翅膀。 目前,我们注意到高校在大力推进数字化建设,在内容管理上遇到以下问题亟待解决: 各个科研实验室资料、项目…

【后端面经-Java】Synchronize和ReentrantLock区别

【后端面经-Java】Synchronize和ReentrantLock区别 1. 概念介绍1.1 线程安全锁1.2 公平锁1.3 响应中断/等待可中断 2. 区别2.1 底层实现2.2 锁的用法2.3 锁的特点2.4 性能比较2.5 适用场景 3. 总结比较参考文献 1. 概念介绍 1.1 线程安全锁 Synchronize(同步锁&am…

Spring Boot 中的 @PutMapping 注解是什么,原理,如何使用

Spring Boot 中的 PutMapping 注解是什么,原理,如何使用 在 Spring Boot 中,PutMapping 是一种注解,它可以将 HTTP PUT 请求映射到指定的处理方法上。本文将介绍 PutMapping 的原理以及如何在 Spring Boot 中使用它。 PutMapping…

【软考网络管理员】2023年软考网管初级常见知识考点(31)-著作权、商标权、专利权详解

涉及知识点 著作权保护期限,著作权人的确定,侵权如何去判定,商标权是什么?专利权详解,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 原创于:CSDN博主-《…

Visual C++中的虚函数和纯虚函数(对比学习法之一)

我是荔园微风,作为一名在IT界整整25年的老兵,今天来说说Visual C中的虚函数和纯虚函数。该系列帖子全部使用我本人自创的对比学习法。也就是当C学不下去的时候,就用JAVA实现同样的代码,然后再用对比的方法把C学会。 直接说虚函数…

初识mysql数据库之表的约束

目录 一、表的约束的概念 二、非空约束(空属性) 2. 空属性的使用 三、default约束(默认值) 1. 默认值的含义 2. 默认值的使用 3. 默认值与非空约束的关系 3.1 默认值与非空约束的生效问题 3.2 default自动生成与not null的…

Linux 学习记录40(C++篇)

Linux 学习记录40(C/QT篇) 本文目录 Linux 学习记录40(C/QT篇)一、QT软件的使用1. 新建工程 二、C语言和C的区别1. C对C的扩充2. C对C的兼容 三、第一个C程序1. cout标准输出流对象(1.介绍:(2. 运算符(3. cout的使用 2. cin标准输出流对象(1.介绍:(3. ci…

python【爬虫】【批量下载】年报抓取

python年报爬取更新 本人测试发现,ju chao网的年报爬取距离我上一篇博客并没有啥变化,逻辑没变,应好多朋友的需要,这里补充代码 import json import osimport requestsweb_url 改成网站的域名,因为csdn屏蔽 def load…

深入了解cookie以及实际项目中的应用

目录 cookie的原理 cookie是不可跨域的 cookie 的属性 Cookie与Session的区别 在git中的应用 cookie的原理 什么是cookie呢? 众所周知:http都是无状态的 但随着 Web 的不断发展,这种 无状态 的特性出现了弊端。当你登录到一家购物网站…

RabbitMQ保证消息的可靠投递,Java实现RabbitMQ消息的可靠投递,Springboot实现RabbitMQ消息的可靠投递

文章目录 一、RabbitMQ消息可靠性概述1、引出问题2、RabbitMQ消息可靠性保证的四个环节 二、保证生产者消息发送到RabbitMQ服务器1、服务端确认:Transaction模式(1)JavaAPI(2)springbootAPI 2、服务端确认:…

【Matlab】根据伯德图计算pid参数方法原理

在学习鲁棒控制的过程中,有一些步骤需要根据一些性能参数来计算pid参数,因此记录一下根据伯德图的性能来计算pid参数的原理。 系统开环响应的几个关键参数 在使用开环响应初调控制器参数时,主要就是调整几个需要注意的关键参数,…

nbcio-vue中formdesigner的组件显示不正常的处理

今天看演示系统的formdesigner组件显示不正常,也不知道是什么时候开始的事情, 如下: 对组件的操作倒是正常,但看本地是正常的,如下: 开始也不知道是什么原因,看代码也是一样的,应该…

11 MFC 制作记事本

文章目录 界面制作制作菜单设置编译框随着窗口的变化而变化OnSize打开文件文件另存为设置字体颜色修改字体文件的查找与替换查找与替换对话框显示(非模态对话框)对话框消息与对话框处理函数 全部代码 界面制作 制作菜单 选择Menu 点击新建 将内容写入&qu…

Nightingle夜莺Docker版SNMP监控

起因 对夜莺很感兴趣,想使用一下。我看官方提供了v6版本的docker-compose。而且我之前有使用过promtheus和grafana,虽然很好但是总觉得还是得二开。总有一天有人去搞一个不错的玩意儿出来。官方文档地址 安装与配置 直接运行docker版本的demo&#xf…

mysql内部结构和InnoDB底层原理

一、mysql内部结构 mysql总体上分为客户端、Server层、引擎层,具体如下图: 1、连接器 一般客户端通过jdbc、navicat等工具发送请求连接到mysql服务端,完成TCP三次握手后,连接器就开始认证身份,如果身份认证成功&…

数据结构-串、数组和广义表

数据结构之串、数组和广义表 串的定义一、串的顺序存储结构1.1、串的链式存储结构1.2、串的模式匹配算法1.2.1、Brute-Force简称为BF算法1.2.2、KMP算法 数组的定义2.1、数组的顺序存储结构2.2、数组的特点:结构固定-----维数和维界不变2.3、特殊矩阵的压缩存储 广义…

密码学—Kasiski测试法Python程序

Kasiski Kasiski是辅助破解Vigenere的前提工作,Kasiski是猜测加密者使用Vigenere密码体系的密钥的长度,Kasiski只是猜测长度而已,所以说是辅助破解Vigenere 若密文中出现两个相同的密文段(密文段的长度m>2),则它们对应的明文&…