Java基础到就业!项目加面试!之Redis面试大全!

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。

1,什么是Redis


简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。


另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。


最主要的Redis就是缓存应用!


2,Redis和Memecache有什么区别?


对于 redis 和 Memecache的区别有下面四点。


a.redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。


b.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中。


c.集群模式:memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 redis 目前是原生支持 cluster 模式的。


d.Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。


3,Redis和Mysql的区别:


redis: 内存型非关系数据库,数据保存在内存中,速度快


mysql:关系型数据库,数据保存在磁盘中,检索的话,会有一定的Io操作,访问速度相对慢


4,为什么要用reids,不用不行吗?


主要从“高性能”和“高并发”这两点来看待这个问题。在这两种情况下Redis非常的快。


首先看一下高性能:


假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!


最重要的就是在高并发的时候,Redis非常的快。


直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。


那么Redis为啥这么快呢?听小孟道来。


如果简单的解释就是:


首先,采用了多路复用io阻塞机制然后,数据结构简单,操作节省时间。并且,Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。最后,运行在内存中,Redis直接自己构建了VM机制 ,不会像一般的系统会调用系统函数处理,自然速度快。


微信图片_20221009201116.png


5,Redis为什么是单线程的?单线程可以处理高并发吗?


Redis的瓶颈不是cpu的运行速度,而往往是网络带宽和机器的内存大小。再说了,单线程切换开销小,容易实现既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。


当然可以处理高并发,Redis不就实现了吗?


6,为什么Redis 6.0 之后改多线程呢?


上面说了Redis是单线程的,Redis6.0之前Redis都是单线程的,就是处理客户端的数据时,读写都由一个顺序串行的主线程处理。


redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。


这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。


它的执行命令操作内存的仍然是个单线程。


微信图片_20221009201121.png



7,Redis的五种类型有那些?


String 整数,浮点数或者字符串,使⽤场景:缓存、计数器、共享 Session、限速。


Set 集合,通常用在兴趣标签之类的。


Zset 有序集合,通常用在排行榜之类的。


Hash 散列表,哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。


List 列表,在 Redis 中,可以队列表两端插⼊和弹出,还可以获取指定范围的元素列表、获取指定索引下的元素等,列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊。


微信图片_20221009201124.png


Set用的比较多,redis的端口号通常是6379:


127.0.0.1:6379> set key1 xiaomeng1
OK
127.0.0.1:6379> set key2 xiaomeng2
OK
127.0.0.1:6379> set key3 xiaomeng3
OK
127.0.0.1:6379> set key4 xiaomeng4
OK
127.0.0.1:6379> set key5 xiaomeng5
OK
127.0.0.1:6379> set key6 xiaomeng6
OK


除此之外,还有三种特殊的数据类型:


Geo:Redis3.2推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。


HyperLogLog:用来做基数统计算法的数据结构。


Bitmaps :用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组。


8,Redis常见的功能有哪些?


1. 数据缓存功能


2. 分布式锁的功能


3. ⽀持数据持久化


4. ⽀持事务


5. ⽀持消息队列


微信图片_20221009201129.png


9,Redis的优缺点有哪些


优点:


上面已经了列举了Redis的很多优点:


1,读写非常的快,提高网站的访问速度,Redis能读的速度是110000次/s,写的速度是81000次/s。强悍的一比。


2,持AOF和RDB两种持久化方式。


3,支持较多的数据结构类型,有String、hash、set、zset等等。


4,支持主从复制,主机可以自动的将数据同步到从机,从而进行读写分离。


5,支持AOF和RDB的持久化方式。


缺点:


任何的事物有优点,必然有缺点。Redis也不例外。


Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。


Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。


10,说说缓存穿透,缓存雪崩以及缓存击穿?


A,缓存穿透:缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据 库的访问压力就会增大,缓存穿透的解决方案,再换个说法就是客户持续向服务器发起对不存在服务器中数据的请求。客户先在Redis中查询,查询不到后去数据库中查询。


缓存穿透的如何避免:


  1. 缓存空对象:如果⼀个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进⾏缓存,但它的过期时间会很短,最⻓不超过五分钟。
  2. 接口层增加校验,对传参进行个校验,比如说我们的id是从1开始的,那么id<=0的直接拦截;
  3. 缓存中取不到的数据,在数据库中也没有取到,这时可以将key-value对写为key-null,这样可以防止攻击用户反复用同一个id暴力攻击
  4. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  5. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。


B,缓存击穿:就是一个很热门的数据,突然失效,而此时大量请求到服务器数据库中。


最好的办法就是设置热点数据永不过期。热点数据快要过期时,异步线程去更新和设置过期时间。


此外还可以采用互斥锁方案。


C,缓存雪崩:概念上是大量数据同一时间失效。此刻无数的请求直接绕开缓存,直 接请求数据库。


造成缓存雪崩的原因,有以下2种: reids宕机,可以通过构造redis集群解决! 大部分数据失效。可通过均匀设置过期时间解决,即让过期时间相对离散一点。


11,说一下Redis的持久化机制。


Redis的持久化机制有RDB和AOF。


RDB把内存数据以快照的形式保存到磁盘上。其核心的配置:


save <seconds> <changes>
# save ""
save 900 1
save 300 10
save 60 10000

可以进行备份和全量复制,但是无法做到实时的持久化。适合大规模的数据恢复。


RDB做不到实时的持久化,但AOF可以。采用日志的形式来记录每个写操作,追加到文件中,通过重启执行AOF来恢复数据。


Redis默认是把AOF关闭的,我们可以把它打开。no改为yes


appendonly yes


AOF数据的完整性和一致性更高,


但是,因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。


基于以上分析,若只打算用Redis 做缓存,可以关闭持久化。


若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。所以还是要根据不同的需求,去做不同的操作。


12,MySQL 里有 1000w 数据,redis 中只存 10w 的数据,如何保证 redis 中的数据都 是热点数据?


redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。其实面试除了考察 Redis,大厂对于底层、分布式、微服务考察很多!


13,说下Redis的淘汰策略?


Redis的淘汰策略有8种,分别为:noeviction,volatile-lru,volatile-lfu,volatile-ttl,volatile-random,allkeylru,allkeys-lfu,allkeys-random


14,请讲一下Redis的应用场景?


我们都知道Redis最主要的就是缓存,在网站中应用最广泛,可以很明显的提高访问的速度,减少数据库的压力!和memcached相比,redis更加的强悍,因为提供了丰富的数据结构,还提供了RDB和AOF等持久化机制。通常运用在如下场景:


微信图片_20221009201140.png


15,如何实现Redis的高可用?


一般有三种模式,分别为主从模式(Replication-Sentinel模式)、哨兵模式、集群模式。


微信图片_20221009201145.png


主从模式:


主从模式是部署多台服务器,有主节点和从节点,主节点负责读写,从节点负责读。


首先是master和slave的连接,然后会将自身的数据复制给slave。


微信图片_20221009201149.png

如果maser和slave断开连接后重新连接,只获取在断开连接期间内丢失的命令流。


如果无法同步,slave 会请求进行全量重同步。


Redis Sentinel(哨兵):


哨兵是社区版本推出的原生高可用解决方案,为什么要提供哨兵?


在主从模式中,主节点发什么问题时,需要人工的将从节点搞成主节点,非常的费事,而且通知应用方更新主节点的地址,更加的费事。哨兵就可以解决这个问题。


哨兵模式的搭建:


#配置端口
port 26379
#以守护进程模式启动
daemonize yes
#日志文件名
logfile "sentinel_26379.log"
#存放备份文件以及日志等文件的目录
dir "/opt/redis/data"
#监控的IP 端口号 名称 sentinel通过投票后认为mater宕机的数量,此处为至少2个
sentinel monitor mymaster 192.168.14.101 6379 2
#30秒ping不通主节点的信息,主观认为master宕机
sentinel down-after-milliseconds mymaster 30000
#故障转移后重新主从复制,1表示串行,>1并行
sentinel parallel-syncs mymaster 1
#故障转移开始,三分钟内没有完成,则认为转移失败
sentinel failover-timeout mymaster 180000

哨兵模式的架构图如下所示:


微信图片_20221009201154.png


集群模式:


Redis 集群是一个提供在多个Redis节点间共享数据的程序集,对数据进行分片,也就是说每台Redis节点上存储不同的内容,来解决在线扩容的问题。哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,并且不好在线扩容。


微信图片_20221009201159.png,


Redis Cluster有一个槽的概念,所有的键根据哈希函数映射到 0~16383 个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据,可以直接自动跳转到这个对应的节点上进行存取操作。


槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
675
分享
相关文章
尼恩一键开发环境: vagrant+java+springcloud+redis+zookeeper镜像下载(&制作详解)
尼恩提供了一系列文章,旨在帮助开发者轻松搭建一键开发环境,涵盖Java分布式、高并发场景下的多种技术组件安装与配置。内容包括但不限于Windows和CentOS虚拟机的安装与排坑指南、MySQL、Kafka、Redis、Zookeeper等关键组件在Linux环境下的部署教程,并附带详细的视频指导。此外,还特别介绍了Vagrant这一虚拟环境部署工具,
尼恩一键开发环境: vagrant+java+springcloud+redis+zookeeper镜像下载(&制作详解)
|
29天前
|
Java社招面试中的高频考点:Callable、Future与FutureTask详解
大家好,我是小米。本文主要讲解Java多线程编程中的三个重要概念:Callable、Future和FutureTask。它们在实际开发中帮助我们更灵活、高效地处理多线程任务,尤其适合社招面试场景。通过 Callable 可以定义有返回值且可能抛出异常的任务;Future 用于获取任务结果并提供取消和检查状态的功能;FutureTask 则结合了两者的优势,既可执行任务又可获取结果。掌握这些知识不仅能提升你的编程能力,还能让你在面试中脱颖而出。文中结合实例详细介绍了这三个概念的使用方法及其区别与联系。希望对大家有所帮助!
167 60
java连接redis和基础操作命令
通过以上内容,您可以掌握在Java中连接Redis以及进行基础操作的基本方法,进而在实际项目中灵活应用。
84 30
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
50 14
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
38 13
|
1月前
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
137 36
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
71 16
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
56 9
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
61 12

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等